Está en la página 1de 5

Upload de

Archivos en PHP
(bsico)

ara subir archivos a travs de formularios HTML desde PHP, disponemos


de un array superglobal llamado $_FILES, el cual nos va a facilitar el
proceso con la ayuda de la funcin nativa move_uploaded_file(). Pero
antes de ver como lograrlo, es necesario tener en cuenta ciertas pautas de
seguridad.

Cuestiones de Seguridad
Siempre que hablemos de permitir al usuario cargar archivos a nuestro
servidor, tenemos la obligacin de comprender qu dicha carga de archivos
puede poner en riesgo la estabilidad del servidor. Esto es debido a que la
carga de archivos no ser posible realizarse, si el directorio en el cul se
pretende efectuar la carga no posee permisos de escritura.
Por tal motivo, siempre es aconsejable, que los directorios que cuenten
con permisos de escritura no se encuentren servidos, es decir, que no
se pueda acceder a ellos, mediante el navegador Web (no deben tener acceso
por medio de una URL).
Otra cuestin fundamental, es que al permitir la carga de archivos al servidor,
deben extremarse al mximo posible, las validaciones sobre el tipo de
archivo que se est subiendo. Esta validacin, siempre deber hacerse,
validando que el type del array $_FILES sea un tipo permitido. Toda
validacin realizada del lado del cliente (con JavaScript, por ejemplo) o sobre la
extensin del archivo, jams ser del todo segura.

Cmo funciona la carga de archivos en PHP


En PHP, tras enviar un formulario, los archivos subidos a travs de campos de
tipo file, son almacenados momentneamente en el directorio temporal del
servidor (generalmente /tmp), procesando su informacin en un array
superglobal llamado $_FILES.
Este array es de tipo multidimensional asociativo. Las claves de este array,
sern los nombres de los campos de tipo file, y el valor asociado a esa clave,
ser otro array asociativo, que almacenar la siguiente informacin:

Nombre del archivo original:


$_FILES['nombre_del_campo_file']['name']
Nombre del archivo almacenado en el directorio temporal:
$_FILES['nombre_del_campo_file']['tmp_name']
Tipo MIME del archivo:
$_FILES['nombre_del_campo_file']['type']
Tamao del archivo (en bytes):
$_FILES['nombre_del_campo_file']['size']

Estos archivos, como comentamos anteriormente, sern almacenados de forma


temporal en el servidor. Entonces, deben moverse a un directorio estable.
Para ello, se utiliza la funcin move_uploaded_file($archivo_temporal,
$destino).

Validacin del tipo MIME


(avanzada)
# Recibo un archivo
$archivo = $_FILES['campo']['tmp_name'];
# Verifico si el tipo MIME es correcto
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($archivo);
$permitidos = array("image/png", "image/jpg");
if(in_array($mime, $permitidos)) {
# Muevo el archivo a un directorio permanente
move_uploaded_file($archivo, $destino);
}

NOTA #1:
El nombre de archivos relacionados a registros en una base de datos, llevarn
como nombre la ID del registro.
Si son varios archivos, se crea una carpeta cuyo nombre sea la ID del registro y
dentro los archivos con cualquier nombre.
Si son varios archivos de distinto tipo (fotos, documentos, videos, etc.) puede
crearse una carpeta cuyo nombre sea la ID y dentro de esta, un directorio para
cada tipo (fotos, documentos, videos, etc.).

NOTA #2:
Para aplicar esta validacin, el php.ini debe estar configurado de la siguiente
manera:
opcin 1 (por defecto):
open_base_dir y upload_tmp_dir vacos

opcin 2 (recomendada / segura):


upload_tmp_dir:
open_basedir

ruta

-no

servida-

dentro

de

la

definida

Mostrar archivos binarios


desde directorios no
accesibles por el navegador
Cuando se trabaja con sistemas de carga de archivos, una buena poltica de
seguridad es almacenarlos en un directorio que no se encuentre servido (es
decir, que no sea accesible por el navegador) puesto que el mismo deber
contar con permisos de escritura.

Cuando los archivos que se cargan son binarios que deben ser mostrados
estticamente desde cdigo HTML -o descargados-, es necesario que el
navegador tenga acceso a ellos.

Para mostrarlos (o permitir su descarga) sin tener que habilitar un directorio


servido con permisos de escritura, el hack consiste en servir los archivos
mediante PHP, leyndolos en modo binario:
# Archivo: file.php
$archivo = "/path/to/private/folder/{$_GET['f']}";
if(file_exists($archivo)) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $archivo);
finfo_close($finfo);
header("Content-Type: $mime");
readfile($archivo);
}

en

Luego, en los archivos HTML se podrn invocar de la siguiente forma:


<img src='file.php?f=imagen.png'>
<a href='file.php?f=archivo.pdf'>Descargar PDF</a>

Mostrar imgenes
contenidas en un archivo
ZIP no accesible desde el
navegador
Este hack implementa el truco anterior para permitir mostrar en HTML,
archivos de imgenes que se encuentran dentro de un ZIP.

// archivo: image_show.php
$archivo_zip = "imagenes.zip";
if(isset($_GET['filename'])) {
$imagen = "zip://$archivo_zip#{$_GET['f']}";
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $imagen);
finfo_close($finfo);
header("Content-Type: $mime");
readfile($imagen);
} else {
$zipobj = new ZipArchive;
$recurso = $zipobj->open($archivo_zip);
$i = 0;
while($nombre = $zipobj->getNameIndex($i)) {
print "<img src='image_show.php?f=$nombre'><br>" . chr(10);
$i++;
}
$zipobj->close();
}

LINKS OFICIALES:
Carga de archivos (especificaciones generales):
http://php.net/manual/es/features.file-upload.post-method.php

Cdigos de error retornados por $_FILES['campo']['error']:


http://php.net/manual/es/features.file-upload.errors.php

Subir mltiples archivos:


http://php.net/manual/es/features.file-upload.multiple.php

Directivas de php.ini que interfieren con la carga de archivos:


http://php.net/manual/es/ini.core.php#ini.sect.file-uploads

También podría gustarte