Guardar archivos enviados por un formulario en el servidor

 
En este artículo se muestra como guardar ficheros subidos desde un formulario al servidor.

El código HTML previo, es un simple formulario con 2 "input file", para subir los archivos, se podría añadir mas input file, o bien poner sólo uno, ya que el código recorrerá todos los ficheros enviados. recordar que el tipo de encriptación para el formulario, debe ser multipart/form-data.
El action, debería ir a la dirección de la página donde queramos ejecutar el script, ya sea en la propia o en otra. En el ejemplo sería la página hermana "guardararchivos.php".

El código PHP, primero establece la url donde se guardarán los ficheros, que deberíamos cambiar por la nuestra:

$sDirGuardar = $_SERVER["DOCUMENT_ROOT"]."/directorio/guardar/";


Aquí deberemos introducir la URL donde nosotros queramos guardar los ficheros, la variable $_SERVER["DOCUMENT_ROOT"] pasa la dirección del directorio raíz donde están los documentos web

El resto del código, recorre los ficheros y en caso de no existir ya un fichero con el mismo nombre, lo guarda en la carpeta seleccionada con la función especifica move_uploaded_file, después establece los permisos de escritura / lectura para todos los usuarios del servidor, ya que el usuario con el que se ejecuta el PHP puede no ser el mismo de, por ejemplo FTP.

Si quisiéramos establecer el nombre del fichero, habría que cambiar la linea (cuidado por si viene mas de un fichero):

$sFichero = $sDirGuardar.$vFichero["name"];


Si quisiéramos que en caso de existir, el fichero se sobreescriba, deberíamos comentar la linea:
if (file_exists($sFichero))
{
    echo "
El archivo ".$vFichero["name"]." ya existe
";
    continue;
}


Si quisiéfecharamos no modificar los permisos del fichero deberíamos comentar:

chmod($sFichero, 0666);



Por último recordar que el directorio donde queramos guardar los archivos, debe tener permisos de escritura para el usuario del servidor que corre el PHP, los permisos se pueden modificar mediante FTP o en linea de comandos (para todos lectura / escritura):
chmod 666 directorio_a_cambiar_permisos

Podemos tener errores si queremos poder recibir archivos grandes, en ese caso, podemos modificar en el php.ini las lineas:

VariableValor por defectoDescripción
max_execution_time30El tiempo máximo de ejecución de los scripts en segundos, a mayor tamaño de fichero, mas tiempo necesitaría
max_input_time60Tiempo máximo de espera de datos, a mayor tamaño, mas debería esperar
post_max_size8M (8 Megas)Tamaño máximo que aceptará PHP para los datos POST, si el archivo es mayor que este valor, no se subirá
file_uploadsOnSi se permite subir ficheros (On) o no (Off)
upload_max_filesize2M (2 Megas)Tamaño máximo permitido para subir ficheros, si el archivo es mayor no se subirá

El "valor por defecto" es el valor que suele venir en la mayoría de las configuraciones estándar de PHP.

Aunque sería mas recomendable crear un fichero .htaccess en el directorio donde subamos los ficheros, de forma que las otras carpetas del servidor y sus correspondientes ficheros PHP no se vean afectadas por los cambios, el archivo .htaccess sería de una forma parecida a esta:

# Tiempo máximo de ejecución (300 segundos, 5 minutos)
php_value max_execution_time 300

# Tiempo máximo de espera de datos (600 segundos, 10 minutos)
php_value max_input_time 600

# Tamaño máximo de los datos de POST (510 Megas)
php_value post_max_size 510M

# Se permite subir archivos
php_value file_uploads On

# Tamaño máximo de los archivos a subir (500 Megas)
php_value upload_max_filesize 500M


HTML:
<!--
    Copyright © McAnam.com
    http://www.mcanam.com/articulos/PHP.php?id=15
-->
<html>
    <head>
        <title>Rellene el formulario</title>
    </head>
    <body>
        <form name='formulario' id='formulario' method='post' action='guardararchivos.php' enctype="multipart/form-data">
            <p>Adjuntar archivo1: <input type='file' name='archivo1' id='archivo1'></p>
            <p>Adjuntar archivo2: <input type='file' name='archivo2' id='archivo2'></p>
            <p align='center'>
                <input type='submit' value='Enviar formulario'>
                <input type='reset' value='resetear formulario'>
            </p>
        </form>
    </body>
</html>

Código:
<?php
// Copyright © McAnam.com
// http://www.mcanam.com/articulos/PHP.php?id=15
    
    function GuardaArchivosFormulario()
    {
        
        // Establecemos el directorio donde se guardan los ficheros
        $sDirGuardar = $_SERVER["DOCUMENT_ROOT"]."/directorio/guardar/";
        $iContFicSubidos = 0;
        
        // Recorremos los Ficheros recibidos
        foreach ($_FILES as $vFichero)
        {
            
            // Se establece el fichero con el nombre original
            $sFichero = $sDirGuardar.$vFichero["name"];
            
            // Si el archivo ya existe, no lo guardamos
            if (file_exists($sFichero))
            {
                echo "<br/>El archivo ".$vFichero["name"]." ya existe<br/>";
                continue;
            }
            
            // Copiamos de la dirección temporal al directorio final
            
            if (filesize($vFichero["tmp_name"]))
                if (!(move_uploaded_file($vFichero["tmp_name"], $sFichero)))
                {
                    echo "<br/>Error al escribir el archivo ".$vFichero["name"]."<br/>";
                }
                else
                {
                    chmod($sFichero, 0666);
                    $iContFicSubidos++;
                }
            
        }
        
        echo "<br/>Fin de ejecución de 'GuardaArchivosFormulario', $iContFicSubidos archivos subidos.<br/>";
        
    }
        
    //Ejemplo de como usar:
    GuardaArchivosFormulario();

?>

Links relacionados:
Formulario para enviar archivos al servidor
Compresión de ficheros con PHP a GZIP
Forzar descarga de ficheros en lado cliente
Enviar un formulario por correo electrónico con adjuntos
Recorrer directorio para tratar su contenido
Variables globales de servidor con $_SERVER
Validar todos los campos de un formulario
Imprimir archivo directamente desde el servidor en impresora de red


Para cualquier duda, consulta, sugerencia, opinión, colaboración, etc; no dude en ponerse en contacto con nosotros

Copyright © 2002-2017 [McAnam]. Reservados todos los derechos.
www.mcanam.com