- Detalles
- Por Juan Padial
- En Programación
- Visto: 47861
Hoy vamos a ver como crear un formulario con la opción de subir archivos utilizando php y html. El proceso de subida se realiza desde el PC del usuario al servidor de tu web utilizando el navegador. Por ello, es necesario que los permisos de la carpeta dónde se van a guardar los archivos subidos sean '777'. Permisos '777' indica que puede ser leído y escrito por el usuario visitante de tu web. En algunas configuraciones de servidor no es necesario y bastará con permisos '755'; si no conoces la configuración de tu servidor prueba con '755' (es más seguro) y si no funciona prueba a cambiarlo a '777'. Antes de seguir puede serte útil echar un vistazo al artículo Manejo de archivos en php.
Vistos los apuntes preliminares comencemos con el groso del artículo, primero veremos la construcción del formulario con html y luego el script php que controlará la subida de los archivos al servidor.
El formulario para subir archivos
Como ejemplo vamos a poner un formulario que va a consistir únicamente en el campo de subida y el botón para enviar el archivo. Puedes añadir los campos que necesites y procesarlos luego en el mismo script php. Pero esto ya no es asunto de este artículo.
Lo más importante a tener en cuenta cuando se construye un formulario para subir archivos al servidor es establecer el atributo enctype del formulario en "multipart/data" y en el campo input donde se va a seleccionar el archivo hay que poner el atributo type="file".
<!DOCTYPE html> <html lang="es"> <head>
<meta charset="utf-8" /> <title>Ejemplo de formulario para subir archivos</title> </head> <body> <div id="formulario"> <form action="subir.php" method="post" enctype="multipart/form-data" name="upload_form"> <label for="archivo">Archivo</label> <input name="archivo" type="file" id="archivo" /> <button name="enviar" type="submit" id="enviar" value="Enviar" /> </form> </div> </body> </html>
El formulario apunta al archivo subir.php, que pondremos en el mismo directorio que el archivo html o php que contenga el formulario. Este archivo contendrá el script que va a procesar la información enviada a través del formulario.
El script php para controlar la subida del archivo
Una vez construido nuestro formulario, pasamos a preparar el script php que procesará la petición de subida de archivo. El siguiente código lo pondremos en subir.php.
<?php
$uploaddir = "uploads/";
$uploadfile = $uploaddir . basename($_FILES['archivo']['name']);
$error = $_FILES['archivo']['error'];
$subido = false;
if(isset($_POST['enviar']) && $error==UPLOAD_ERR_OK) {
$subido = copy($_FILES['archivo']['tmp_name'], $uploadfile);
}
if($subido) {
echo "El archivo se guardó con éxito";
} else {
echo "Se ha producido un error: ".$error;
}
?>
Veamos este código paso por paso:
- $uploaddir: Esta variable contiene el directorio donde vamos a subir los archivos enviados a través del formulario. Es importante como escribimos el valor de esta variable. En el ejemplo escribimos $uploaddir = "uploads/", esto quiere decir que en el mismo directorio donde tenemos el archivo subir.php existe el directorio "uploads"; si este directorio no está, php dará un error al copiar el archivo subido. Otra forma de poner el directorio de subida es con el path absoluto, por ejemplo, en el servidor donde está alojado en este dominio seria $uploaddir = "/home/bloogie/public_html/undirectorio/el_directorio_de_subidas/". Nota como siempre tenemos que poner el último "/" y que cuando ponemos el path absoluto también ponemos un "/" al principio.
- $uploadfile: En esta variable juntamos el directorio de subida con el nombre del archivo subido, de esta forma construimos la ruta a la que será copiado el archivo subido.
- $_FILES: esta es una variable superglobal que contiene un array con información del archivo subido por método POST (como es nuestro caso). La variable $HTTP_POST_FILES contiene la misma información pero es obsoleta desde php 4.1.0. Nuestro input para el archivo se llamaba "archivo" por lo que para obtener la información del archivo subido utilizaremos $_FILES['archivo']['info_a_obtener']. Entre la info más importante que podemos obtener está name (nombre), size (tamaño en bytes), type (contiene el MIME, por ejemplo "image/gif" para una imagen tipo gif), tmp_name (contiene la ruta temporal del archivo subido) y error (contiene el código de error del proceso de subida, será 0 si no hay ningún error).
- $error: aquí vamos a guardar el código de error. Para posteriores comprobonaciones.
- $subido: la variable que usaré para comprobar si finalmente el archivo se ha subido y guardado correctamente donde deseo.
La siguiente parte del código es comprobar que venimos del formulario (isset($_POST['boton'])) y que no hay error en la subida del archivo ($error==UPLOAD_ERR_OK). UPLOAD_ERR_OK tiene valor 0 por lo que también sería válido comparar la variable $error con 0 (más info en errores en el Manual de PHP).
Bien, una vez comprobado que no hay error, realizamos la copia del archivo subido desde el directorio temporal a su ubicación definitiva cuya ruta ya construimos y almacenamos en la variable $uploadfile. Si se copia de forma satisfactoria la variable $subido será = true y lanzaremos un mensaje de éxito, de lo contrario se mostrará un mensaje de error incluyendo el código del error (visita el link que deje unas líneas más arriba sobre los códigos de errores al subir archivos).
Aunque el tamaño máximo para subida de archivos puede especificarse en la directiva upload_max_filesize establecida en la configuración de php, puede que no tengas acceso a esta configuración o que quieras limitar el tamaño de subida específicamente para este formulario. Así que compliquemos un poco más el script php con la comprobación del nombre, tipo y tamaño del archivo subido.
<?php
$uploaddir = "uploads/";
$uploadfilename = strtolower(str_replace(" ", "_",basename($_FILES['archivo']['name'])));
$uploadfile = $uploaddir.$uploadfilename;
$error = $_FILES['archivo']['error'];
$subido = false;
if(isset($_POST['boton']) && $error==UPLOAD_ERR_OK) {
if($_FILES['archivo']['type']!="image/gif" || $_FILES['archivo']['size'] > 100000) {
$error = "Comprueba que el archivo sea una imagen en formato gif y de tamano inferior a 10Kb.";
} elseif(preg_match("/[^0-9a-zA-Z_.-]/",$uploadfilename)) {
$error = "El nombre del archivo contiene caracteres no válidos.";
} else {
$subido = copy($_FILES['archivo']['tmp_name'], $uploadfile);
}
}
if($subido) {
echo "El archivo se guardó con éxito";
} else {
echo "Se ha producido un error: ".$error;
}
?>
Este script solo permitiría la subida de archivos de imagen en formato gif y de un tamaño inferior a 100Kb. Toma nota de la comprobación del nombre del archivo para que no contenga espacios ni caracteres no alfanuméricos (ni otros caracteres especiales como la ñ, que darían problemas en la inmensa mayoría de servidores que están basados en unix).
Procesamiento en la misma página
Hacer todo en una misma página suele ser más user friendly, así que vamos a ponerlo todo junto para que el formulario se procese en la misma página que se muestra. Si os preguntáis por hacer la subida de archivos con ajax, os diré que no se pueden subir archivos con ajax y hay que dar algunos rodeos: utilizar flash, un formulario camuflado en un iframe o una técnica diferente para cada navegador para que sea estrictamente ajax. Dada la extensión que supone la explicación, le dedicaré un artículo entero a ese tema y por ahora os dejo el formulario para subir archivos procesado en la misma página pero sin ajax.
<?php
if($_POST['enviar']) {
$uploaddir = "uploads/";
$uploadfile = $uploaddir . basename($_FILES['archivo']['name']);
$error = $_FILES['archivo']['error'];
$subido = false;
if($error==UPLOAD_ERR_OK) {
if($_FILES['archivo']['type']!="image/gif" || $_FILES['archivo']['size'] > 100000) {
$error = "Comprueba que el archivo sea una imagen en formato gif y de tamano inferior a 10Kb.";
} elseif(preg_match("/[^0-9a-zA-Z_.-]/",$uploadfilename)) {
$error = "El nombre del archivo contiene caracteres no válidos.";
} else {
$subido = copy($_FILES['archivo']['tmp_name'], $uploadfile);
}
}
if($subido) {
$message = "El archivo se guardó con éxito";
} else {
$message = "Se ha producido un error: ".$error;
}
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Ejemplo de formulario para subir archivos en PHP</title>
</head>
<body>
<div id="formulario">
<?php if(isset($message)) : ?>
<div id="message">
<?php
echo $message;
?>
</div>
<?php endif; ?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" enctype="multipart/form-data" name="upload_form">
<label for="archivo">Archivo</label>
<input name="archivo" type="file" id="archivo" />
<button type="submit" id="enviar">Subir archivo</button>
</form>
</div>
</body>
</html>
Nota: No me hago responsable si utilizas el código mostrado y este contiene errores o fallas de seguridad que pudieran comprometer algún aspecto de tu web.
Creado el 23 05 2011 Actualizado el 08 02 2013
