Cómo Subir un Archivo en PHP (Con Ejemplo)
Spanish (Español) translation by Rene Soto (you can also view the original English article)
En este artículo, explicaré los conceptos básicos de la carga de archivos en PHP. En primer lugar, veremos las opciones de configuración de PHP que se deben implementar para que los archivos se carguen correctamente. A continuación, desarrollaremos un ejemplo real de cómo cargar un archivo.
Configurar las Opciones de PHP
Hay un par de ajustes de configuración de PHP
que querrás verificar de antemano para cargar archivos correctamente. En esta sección, veremos todas y cada una de las opciones que
son importantes en lo que respecta a la carga de archivos PHP. Estas opciones
se pueden configurar en el archivo php.ini.
Si no estás seguro de dónde encontrar tu archivo php.ini,
puedes usar php_ini_loaded_file() para localizarlo. Simplemente crea un archivo
PHP en su servidor con la siguiente línea y ábrelo desde el navegador.
1 |
<?php echo php_ini_loaded_file(); ?> |
Aquí hay un extracto de un archivo de configuración con algunos valores predeterminados útiles.
1 |
; Whether to allow HTTP file uploads. |
2 |
file_uploads = On |
3 |
|
4 |
; Temporary directory for HTTP uploaded files. |
5 |
; Will use system default if not set. |
6 |
;upload_tmp_dir = |
7 |
|
8 |
; Maximum allowed size for uploaded files. |
9 |
upload_max_filesize = 16M |
10 |
|
11 |
; Maximum number of files that can be uploaded via a single request |
12 |
max_file_uploads = 20 |
13 |
|
14 |
; Maximum size of POST data that PHP will accept. |
15 |
post_max_size = 20M |
16 |
|
17 |
max_input_time = 60 |
18 |
memory_limit = 128M |
19 |
max_execution_time = 30 |
Configuraciones Clave
file_uploads
El valor de la
directiva file_uploads se debe establecer en On para permitir la carga de
archivos. El valor predeterminado de esta directiva es On.
upload_max_filesize
La directiva
upload_max_filesize te permite configurar el tamaño máximo del archivo cargado. De forma predeterminada, se establece en 2M (dos megabytes), y puede anular
esta configuración utilizando el archivo .htaccess también. Dos megabytes no
son mucho para los estándares de hoy, por lo que es posible que tenga que
aumentar esto. Si recibes un error de cuando el archivo excede upload_max_filesize cuando intenta cargar un archivo, debes aumentar este valor. Si lo hacea, asegúrate de aumentar también post_max_size (ver más abajo).
upload_tmp_dir
Establece un directorio temporal que se utilizará para almacenar los archivos cargados. En la mayoría de los casos, no necesita preocuparse por esta configuración. Si no lo configuras, se utilizará el directorio temporal predeterminado del sistema.
post_max_size
La directiva
post_max_size te permite configurar el tamaño máximo de los datos POST. Dado
que los archivos se cargan con solicitudes POST, este valor debe ser mayor que
lo que has establecido para la directiva upload_max_filesize. Por ejemplo, si tu
upload_max_filesize es 16M (16 megabytes), es posible que desee establecer
post_max_size en 20M.
max_file_uploads
Te permite
establecer el número máximo de archivos que se pueden cargar a la vez. El valor
predeterminado es 20, una cantidad razonable.
max_input_time
Es el número
máximo de segundos que un script puede analizar los datos de entrada. Debe
establecerlo en un valor razonable si está tratando con cargas de archivos
grandes. 60 (60 segundos) es un buen valor para la mayoría de las aplicaciones.
memory_limit
La directiva
memory_limit indica la cantidad máxima de memoria que puede consumir un script.
Si tienes problemas durante la carga de
archivos grandes, debe asegurarse de que el valor de esta directiva sea mayor
que lo que ha establecido para la directiva post_max_size. El valor predeterminado
es 128M (128 megabytes), así que, a menos que tenga un post_max_size y
upload_max_filesize muy grande, no debe preocuparse por esto.
max_execution_time
Es el número
máximo de segundos que se permite ejecutar un script. Si tiene problemas durante
la carga de archivos grandes, puede considerar aumentar este valor. 30 (30
segundos) deberían funcionar bien para la mayoría de las aplicaciones.
Ahora
construyamos un ejemplo práctico para demostrar la carga de archivos en PHP.
Crear el Formulario HTML
Una vez que hayas configurado la configuración de PHP, estarás listo para probar las capacidades de carga de archivos de PHP.
Nuestro repositorio de GitHub tiene un código de muestra que analizaré a lo largo de este artículo. Por lo tanto, si deseas seguirlo, sigue adelante y descárgalo desde GitHub.
Vamos a crear dos archivos PHP: index.php y upload.php. El archivo index.php contiene el código que es responsable de mostrar el formulario de carga de archivos. Por otro lado, el archivo upload.php es responsable de cargar un archivo en el servidor.
Además, un archivo se cargará en el directorio uploaded_files, por lo que debes asegurarte de que esta carpeta exista y que el usuario del servidor web pueda escribir en ella.
En esta sección, veremos las partes clave del archivo index.php.
Echemos un vistazo al archivo index.php en GitHub:
1 |
<?php
|
2 |
session_start(); |
3 |
?>
|
4 |
<!DOCTYPE html>
|
5 |
<html>
|
6 |
<head>
|
7 |
<title>PHP File Upload</title> |
8 |
</head>
|
9 |
<body>
|
10 |
<?php
|
11 |
if (isset($_SESSION['message']) && $_SESSION['message']) |
12 |
{
|
13 |
printf('<b>%s</b>', $_SESSION['message']); |
14 |
unset($_SESSION['message']); |
15 |
}
|
16 |
?>
|
17 |
<form method="POST" action="upload.php" enctype="multipart/form-data"> |
18 |
<div>
|
19 |
<span>Upload a File:</span> |
20 |
<input type="file" name="uploadedFile" /> |
21 |
</div>
|
22 |
|
23 |
<input type="submit" name="uploadBtn" value="Upload" /> |
24 |
</form>
|
25 |
</body>
|
26 |
</html>
|
Aunque puede parecer un formulario PHP típico, hay una diferencia importante en el valor del atributo enctype de la etiqueta <form>. Debe configurarse en multipart / form-data ya que el formulario contiene el campo de archivo.
El atributo enctype especifica el tipo de codificación que se debe usar cuando se envía el formulario, y toma uno de los siguientes tres valores:
-
application / x-www-form-urlencoded: este es el valor predeterminado cuando no establece el valor del atributoenctypeexplícitamente. En este caso, los caracteres se codifican antes de que se envíen al servidor. Si no tienes el campo de archivo en su formulario, debes usar este valor para el atributoenctype. -
multipart / form-data: cuando utiliza el valormultipart / form-datapara el atributoenctype, te permite cargar archivos utilizando el método POST. Además, se asegura de que los caracteres no estén codificados cuando se envíe el formulario. -
text / plain: Generalmente no se usa. Con esta configuración, los datos se envían sin codificar.
A continuación, generamos el campo de archivo, que te permite seleccionar un archivo de su computadora.
1 |
<input type="file" name="uploadedFile" /> |
Aparte de eso, hemos mostrado un mensaje en la parte superior del formulario. Este mensaje muestra el estado de la carga del archivo y el script upload.php lo configurará en una variable de sesión. Veremos más de esto en la siguiente sección.
1 |
<?php
|
2 |
if (isset($_SESSION['message']) && $_SESSION['message']) |
3 |
{
|
4 |
printf('<b>%s</b>', $_SESSION['message']); |
5 |
unset($_SESSION['message']); |
6 |
}
|
7 |
?>
|
Así que eso resume el archivo index.php. En la siguiente sección, veremos cómo manejar el archivo cargado en el lado del servidor.
Crear la Lógica de Carga
En la sección anterior, creamos el formulario HTML que se muestra en el lado del cliente y te permite cargar un archivo desde su computadora. En esta sección, veremos la contraparte del lado del servidor que le permite manejar el archivo cargado.
Extrae el código del archivo upload.php en GitHub. Revisaremos las partes importantes de ese archivo.
En el archivo upload.php, hemos comprobado si se trata de una solicitud POST válida en primer lugar.
1 |
if (isset($_POST['uploadBtn']) && $_POST['uploadBtn'] == 'Upload') { |
2 |
...
|
3 |
}
|
En PHP, cuando se carga un archivo, la variable superglobal $ _FILES se rellena con toda la información sobre el archivo cargado. Se inicializa como un arreglo y puede contener la siguiente información para la carga exitosa de archivos.
-
tmp_name:La ruta temporal donde se carga el archivo se almacena en esta variable. -
name: El nombre real del archivo se almacena en esta variable. -
size: Indica el tamaño del archivo cargado en bytes. -
type: Contiene el tipo mime del archivo cargado. -
error: Si hay un error durante la carga del archivo, esta variable se rellena con el mensaje de error correspondiente. En el caso de que se cargue correctamente el archivo, contiene 0, que puede comparar utilizando la constanteUPLOAD_ERR_OK.
Después de validar la solicitud POST, verificamos que la carga del archivo se realizó correctamente.
1 |
if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK) { |
2 |
...
|
3 |
}
|
Puedes ver que la variable $_FILES es un arreglo multidimensional,
el primer elemento es el nombre del campo de archivo, y el segundo elemento
tiene la información sobre el archivo cargado, como acabamos de comentar.
Si la carga del archivo es exitosa, inicializamos algunas variables con información sobre el archivo cargado.
1 |
// get details of the uploaded file
|
2 |
$fileTmpPath = $_FILES['uploadedFile']['tmp_name']; |
3 |
$fileName = $_FILES['uploadedFile']['name']; |
4 |
$fileSize = $_FILES['uploadedFile']['size']; |
5 |
$fileType = $_FILES['uploadedFile']['type']; |
6 |
$fileNameCmps = explode(".", $fileName); |
7 |
$fileExtension = strtolower(end($fileNameCmps)); |
En el fragmento anterior, también hemos descubierto la
extensión del archivo cargado y lo hemos almacenado en la variable $fileExtension.
Como el archivo cargado puede contener espacios y otros caracteres especiales, es mejor limpiar el nombre del archivo, y eso es exactamente lo que hemos hecho en el siguiente fragmento de código.
1 |
$newFileName = md5(time() . $fileName) . '.' . $fileExtension; |
Es importante que restrinjas el tipo de archivo que se puede cargar a ciertas extensiones y no permita que todo use el formulario de carga. Lo hemos hecho al verificar la extensión del archivo cargado con un conjunto de extensiones que queremos permitir la carga.
1 |
$allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'doc'); |
2 |
if (in_array($fileExtension, $allowedfileExtensions)) { |
3 |
...
|
4 |
}
|
Finalmente, usamos la función move_uploaded_file para mover
el archivo cargado a la ubicación específica de nuestra elección.
1 |
// directory in which the uploaded file will be moved
|
2 |
$uploadFileDir = './uploaded_files/'; |
3 |
$dest_path = $uploadFileDir . $newFileName; |
4 |
|
5 |
if(move_uploaded_file($fileTmpPath, $dest_path)) |
6 |
{
|
7 |
$message ='File is successfully uploaded.'; |
8 |
}
|
9 |
else
|
10 |
{
|
11 |
$message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.'; |
12 |
}
|
La función move_uploaded_file toma dos argumentos. El primer
argumento es el nombre de archivo del archivo cargado, y el segundo argumento
es la ruta de destino a la que desea mover el archivo.
Finalmente, redirigimos al usuario al archivo index.php. Además, establecemos el mensaje apropiado en la variable de sesión, que se mostrará a los usuarios después de la redirección en el archivo index.php.
Cómo Funciona Todo Junto
No olvides crear el directorio uploaded_files y hacer que el usuario del servidor web pueda escribir en él. A continuación, siga adelante y ejecute el archivo index.php, que debe mostrar el formulario de carga del archivo que se ve así:



Haz clic en el botón Browse que debería abrir un cuadro de diálogo que te permite seleccionar un archivo de su computadora. Selecciona un archivo con una de las extensiones permitidas en nuestro script y haz clic en el botón Upload.
Deberías enviar el formulario y, si todo va bien, deberías ver el archivo cargado en el directorio uploaded_files. También puedes intentar cargar otros archivos con extensiones que no están permitidas y verificar si nuestro script evita dichas cargas.
Conclusión
Hoy, discutimos los conceptos básicos de la carga de archivos en PHP. En la primera mitad del artículo, discutimos las diferentes opciones de configuración que deben estar en su lugar para que la carga de archivos funcione. Luego vimos un ejemplo práctico que demostró cómo funciona la carga de archivos en PHP.
Espero que hayas disfrutado de este artículo, y no dudes en publicar tus consultas y sugerencias en la caja de comentarios abajo.



