Manejando la carga de archivos
PHP Manual

Carga con el método POST

Esta característica permite que los usuarios envien tanto archivos de texto como binarios. Con la autenticación de PHP y las funciones de manipulación de archivos, se tiene completo control sobre quién está autorizado a cargar y que hay que hacer con el archivo una vez que se ha cargado.

PHP es capaz de recibir cargas de archivos de cualquier navegador compatible con RFC-1867.

Nota: Configuraciones Relacionadas

Ver también las directivas file_uploads, upload_max_filesize, upload_tmp_dir, post_max_size y max_input_time en php.ini

PHP también soporta el método PUT para la carga como lo utilizan los clientes Netscape Composer y Amaya del W3C. Ver el soporte del método PUT para más detalles.

Ejemplo #1 Formulario para la carga de archivos

Una página de carga de archivos puede ser construida mediante la creación de un formulario especial el cual se vería algo como esto:

<!-- El tipo de codificación de datos, enctype, se DEBE especificar como a continuación -->
<form enctype="multipart/form-data" action="__URL__" method="POST">
    <!-- MAX_FILE_SIZE debe preceder el campo de entrada de archivo -->
    <input type="hidden" name="MAX_FILE_SIZE" value="30000" />
    <!-- El nombre del elemento de entrada determina el nombre en el array $_FILES -->
    Enviar este archivo: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
</form>

El __URL__ en el ejemplo anterior se debe sustituir y apuntar a un archivo PHP.

El campo oculto MAX_FILE_SIZE (medido en bytes) debe preceder al campo de entrada de archivo y su valor es el tamaño máximo de archivo aceptado por PHP. Este elemento del formulario se debe usar siempre, ya que evita a los usuarios la molestia de esperar a que un gran archivo sea transferido sólo para descubrir que era demasiado grande y falló la transferencia. Tener en cuenta: engañar a esta configuración en el lado del navegador es muy fácil, así que nunca se debe confiar en que archivos con un tamaño mayor serán bloqueados por esta característica. Es simplemente una característica de conveniencia para los usuarios en el lado cliente de la aplicación. Sin embargo, la configuración de PHP (en el lado del servidor) para un máximo de tamaño, no puede ser engañada.

Nota:

Asegúrese de que el formulario de subida de archivos tiene el atributo enctype="multipart/form-data" de lo contrario la carga de archivos no funcionará.

El $_FILES global existe a partir de PHP 4.1.0 (Usar $HTTP_POST_FILES en su lugar si se utiliza una versión anterior). Este array contendrá toda la información sobre el archivo cargado.

El contenido de $_FILES del formulario de ejemplo es el siguiente. Tenga en cuenta que esto asume la utilización del nombre del archivo cargado userfile, tal como se utiliza en el script de ejemplo anterior. Este puede ser cualquier nombre.

$_FILES['userfile']['name']

El nombre original del archivo en la máquina cliente.

$_FILES['userfile']['type']

El tipo mime del archivo, si el navegador proporciona esta información. Un ejemplo podría ser "image/gif". Este tipo mime, sin embargo no se verifica en el lado de PHP y por lo tanto no se garantiza su valor.

$_FILES['userfile']['size']

El tamaño, en bytes, del archivo subido.

$_FILES['userfile']['tmp_name']

El nombre temporal del archivo en el cual se almacena el archivo cargado en el servidor.

$_FILES['userfile']['error']

El código de error asociado a esta carga de archivo. Este elemento fue añadido en PHP 4.2.0

Los archivos, por defecto se almacenan en el directorio temporal por defecto del servidor, a menos que otro lugar haya sido dado con la directiva upload_tmp_dir en php.ini. El directorio por defecto del servidor puede ser cambiado mediante el establecimiento de la variable de entorno TMPDIR en el entorno en el cual se ejecuta PHP. Configurarlo usando putenv() desde un script PHP no funcionará. Esta variable de entorno también se puede utilizar para asegurarse de que las demás operaciones están trabajando sobre los archivos cargados.

Ejemplo #2 Validación de la carga de archivos

Ver también las entradas para las funciones is_uploaded_file() y move_uploaded_file() para más información. El siguiente ejemplo procesaría la carga de archivo que vendría de un formulario.

<?php
// En versiones de PHP anteriores a 4.1.0, $HTTP_POST_FILES debe utilizarse en lugar
// de $_FILES.

$uploaddir '/var/www/uploads/';
$uploadfile $uploaddir basename($_FILES['userfile']['name']);

echo 
'<pre>';
if (
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo 
"El archivo es válido y fue cargado exitosamente.\n";
} else {
    echo 
"¡Posible ataque de carga de archivos!\n";
}

echo 
'Aquí hay más información de depurado:';
print_r($_FILES);

print 
"</pre>";

?>

El script PHP que recibe el archivo cargado, debe implementar cualquier lógica que sea necesaria para determinar qué se debe hacer con el archivo subido. Se puede, por ejemplo, utilizar la variable $_FILES['userfile']['size'] para descartar cualquier archivo que sea demasiado pequeño o demasiado grande. Se podría utilizar la variable $_FILES['userfile']['type'] para descartar cualquier archivo que no corresponda con un cierto criterio de tipo, pero usando esto sólo como la primera de una serie de verificaciones, debido a que este valor está completamente bajo el control del cliente y no se comprueba en el lado de PHP. A partir de PHP 4.2.0, se puede usar $_FILES['userfile']['error'] y el planear la lógica de acuerdo con los códigos de error. Cualquiera que sea la lógica, se debe borrar el archivo del directorio temporal o moverlo a otra parte.

Si ningún archivo es seleccionado para realizar la carga en el formulario, PHP devolverá $_FILES['userfile']['size'] como 0, y $_FILES['userfile']['tmp_name'] como ninguno.

El archivo será borrado del directorio temporal al final de la solicitud si no se ha movido o renombrado.

Ejemplo #3 Cargando un array de archivos

PHP soporta las funcionalidades array de HTML incluso con archivos.

<form action="" method="post" enctype="multipart/form-data">
<p>Pictures:
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="file" name="pictures[]" />
<input type="submit" value="Send" />
</p>
</form>
<?php
foreach ($_FILES["pictures"]["error"] as $key => $error) {
    if (
$error == UPLOAD_ERR_OK) {
        
$tmp_name $_FILES["pictures"]["tmp_name"][$key];
        
$name $_FILES["pictures"]["name"][$key];
        
move_uploaded_file($tmp_name"data/$name");
    }
}
?>

Una barra de progreso de carga de archivos puede ser implementada mediante Session Upload Progress.


Manejando la carga de archivos
PHP Manual