$_FILES en PHP

En el desarrollo de aplicaciones web, a menudo es necesario permitir que los usuarios suban archivos al servidor para almacenarlos o procesarlos. PHP, como uno de los lenguajes de programación web más populares, ofrece una solución integrada y fácil de usar para gestionar la subida y el manejo de archivos a través de la superglobal $_FILES.

En este artículo, exploraremos los conceptos fundamentales, la sintaxis y las operaciones más comunes relacionadas con $_FILES en PHP, proporcionando ejemplos prácticos y detallados para ayudarte a dominar esta funcionalidad esencial.

Ya sea que estés desarrollando un sistema de gestión de contenido, una aplicación para compartir imágenes, o cualquier otro tipo de aplicación que requiera el manejo de archivos, comprender cómo utilizar $_FILES en PHP te permitirá implementar estas funcionalidades de manera eficiente y segura.

Acompáñanos en este recorrido para aprender todo lo que necesitas saber sobre la subida y manejo de archivos en PHP.

¿Qué es $_FILES en PHP?

$_FILES es una superglobal en PHP que se utiliza para gestionar la subida de archivos en aplicaciones web. Cuando un usuario sube un archivo a través de un formulario HTML, PHP crea automáticamente un array asociativo llamado $_FILES que contiene información sobre el archivo subido, como su nombre, tipo, tamaño y ubicación temporal en el servidor.

La superglobal $_FILES es accesible desde cualquier parte del script PHP y no requiere la declaración previa de la variable. Esto facilita el manejo de archivos subidos al servidor, permitiendo realizar validaciones, moverlos a ubicaciones permanentes o procesarlos según sea necesario.

La superglobal $_FILES y su estructura

La estructura de la superglobal $_FILES es un array asociativo multidimensional que contiene información sobre los archivos subidos.

Para cada archivo, se proporciona la siguiente información:

  • $_FILES[‘campo’][‘name’]: El nombre original del archivo en el equipo del usuario.
  • $_FILES[‘campo’][‘type’]: El tipo MIME del archivo, como ‘image/jpeg’ o ‘application/pdf’.
  • $_FILES[‘campo’][‘size’]: El tamaño del archivo en bytes.
  • $_FILES[‘campo’][‘tmp_name’]: La ubicación temporal del archivo en el servidor.
  • $_FILES[‘campo’][‘error’]: Un código de error que indica si la subida del archivo fue exitosa o si ocurrió algún problema.

Donde ‘campo’ corresponde al valor del atributo name del campo input type=”file” en el formulario HTML.

Es importante mencionar que si se permite la subida de múltiples archivos, la estructura de $_FILES se organizará en un array más profundo que contendrá información sobre cada archivo subido.

Configuración del servidor y límites de carga

Antes de permitir la subida de archivos en tu aplicación web, es importante configurar correctamente el servidor PHP. Esto se hace a través del archivo “php.ini”, que contiene varias opciones que controlan el comportamiento del servidor.

Algunas de las opciones más importantes relacionadas con la subida de archivos son:

  • upload_max_filesize: Define el tamaño máximo permitido para un archivo individual. Por ejemplo, si deseas permitir archivos de hasta 2 MB, puedes configurarlo así:

upload_max_filesize = 2M

Lenguaje del código: Makefile (makefile)
  • post_max_size: Establece el tamaño máximo de los datos que se pueden enviar a través del método POST. Asegúrate de que este valor sea mayor o igual al valor de «upload_max_filesize». Por ejemplo:

post_max_size = 8M

Lenguaje del código: Makefile (makefile)
  • max_execution_time: Determina el tiempo máximo en segundos que un script PHP puede ejecutarse antes de ser detenido. Aumenta este valor si la subida de archivos grandes está tardando mucho tiempo. Por ejemplo, para permitir una ejecución de hasta 5 minutos, configura:

max_execution_time = 300

Lenguaje del código: Makefile (makefile)

Modificación de parámetros en tiempo de ejecución

En algunos casos, es posible que no tengas acceso al archivo “php.ini” o prefieras modificar estas opciones solo para ciertas partes de tu aplicación. Puedes hacer esto utilizando la función ini_set() en tu script PHP.

Por ejemplo:


// Establecer el tamaño máximo de archivo a 2 MB
ini_set('upload_max_filesize', '2M');

// Establecer el tamaño máximo de datos POST a 8 MB
ini_set('post_max_size', '8M');

// Establecer el tiempo máximo de ejecución a 5 minutos
ini_set('max_execution_time', 300);

Lenguaje del código: PHP (php)

Ten en cuenta que estos cambios solo afectarán al script PHP en el que se realicen y no a toda la configuración del servidor.

Al configurar correctamente el servidor y los límites de carga, podrás garantizar que tu aplicación maneje la subida de archivos de manera eficiente y segura.

En los siguientes apartados, aprenderemos cómo crear formularios HTML para subir archivos y cómo procesarlos en PHP utilizando la superglobal $_FILES.

Creación y configuración de formularios HTML para subir archivos

Para permitir la subida de archivos en tu aplicación web, primero debes crear un formulario HTML que incluya un campo especial para seleccionar y enviar archivos. A continuación, se explican los atributos clave que debes configurar en tu formulario y en el campo de entrada de archivos.

Atributo enctype="multipart/form-data"

El atributo enctype en la etiqueta del formulario indica cómo se deben codificar los datos antes de enviarlos al servidor. Para subir archivos, debes usar el valor “multipart/form-data”, que permite enviar archivos binarios junto con los demás campos del formulario.

Por ejemplo:


<form action="subir.php" method="POST" enctype="multipart/form-data">
  <!-- Campos del formulario -->
</form>

Lenguaje del código: HTML, XML (xml)

Atributo type="file" en el campo input

Para permitir la selección de archivos en tu formulario, debes agregar un campo de entrada (input) con el atributo type establecido en “file”. Este campo mostrará un botón que permitirá a los usuarios buscar y seleccionar un archivo de su equipo.

Por ejemplo:


<input type="file" name="miArchivo">

Lenguaje del código: HTML, XML (xml)

El atributo name en el campo de entrada es importante, ya que se utilizará para acceder a la información del archivo en PHP a través de la superglobal $_FILES.

Atributo name para identificar el archivo enviado

El atributo name en el campo input type="file" permite identificar el archivo subido al acceder a la información en la superglobal $_FILES en el script PHP.

Por ejemplo:


<form action="subir.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="miArchivo">
  <button type="submit">Subir archivo</button>
</form>

Lenguaje del código: HTML, XML (xml)

En este ejemplo, un usuario puede seleccionar un archivo y enviarlo al servidor haciendo clic en el botón “Subir archivo”. La información del archivo se enviará al script “subir.php”, donde podrás acceder a ella utilizando la superglobal $_FILES y el valor del atributo name del campo input, en este caso, “miArchivo”.

Ahora que hemos configurado un formulario HTML para subir archivos, en los siguientes apartados, aprenderemos cómo procesar y validar los archivos subidos en PHP utilizando la superglobal $_FILES.

Procesamiento y validación de archivos subidos con PHP

Una vez que el usuario haya enviado un archivo mediante el formulario HTML, es necesario procesarlo y validar su contenido en el script PHP. Esto incluye verificar si la subida fue exitosa, si el archivo cumple con ciertos requisitos y, finalmente, moverlo a su ubicación final en el servidor.

Acceso a la información del archivo en $_FILES

Para acceder a la información del archivo subido, utiliza la superglobal $_FILES y el valor del atributo name del campo input type="file" en tu script PHP.

Por ejemplo, en el archivo “subir.php”:


// Verificar si se subió un archivo
if (isset($_FILES['miArchivo'])) {
    $nombre = $_FILES['miArchivo']['name'];
    $tipo = $_FILES['miArchivo']['type'];
    $tamano = $_FILES['miArchivo']['size'];
    $temporal = $_FILES['miArchivo']['tmp_name'];
    $error = $_FILES['miArchivo']['error'];
}

Lenguaje del código: PHP (php)

Validación del archivo (tamaño, tipo, errores de carga)

Antes de mover el archivo a su ubicación final, es importante validar su contenido para garantizar que cumple con los requisitos de tu aplicación.

Por ejemplo, puedes verificar el tamaño, el tipo y si ocurrieron errores durante la carga:


// Verificar si se subió un archivo sin errores
if (isset($_FILES['miArchivo']) && $_FILES['miArchivo']['error'] == 0) {
    // Tamaño máximo permitido en bytes (2 MB)
    $tamanoMaximo = 2 * 1024 * 1024;

    // Tipos de archivo permitidos (jpg y png)
    $tiposPermitidos = ['image/jpeg', 'image/png'];

    // Validar tamaño y tipo del archivo
    if ($_FILES['miArchivo']['size'] <= $tamanoMaximo && in_array($_FILES['miArchivo']['type'], $tiposPermitidos)) {
        // Procesar el archivo
    } else {
        echo "El archivo no cumple con los requisitos de tamaño o tipo.";
    }
} else {
    echo "Error al subir el archivo.";
}

Lenguaje del código: PHP (php)

Mover el archivo a su ubicación final (move_uploaded_file)

Una vez que hayas validado el archivo, puedes moverlo a su ubicación final en el servidor utilizando la función move_uploaded_file().

Por ejemplo:


$directorioDestino = 'uploads/';
$ubicacionFinal = $directorioDestino . basename($_FILES['miArchivo']['name']);

if (move_uploaded_file($_FILES['miArchivo']['tmp_name'], $ubicacionFinal)) {
    echo "El archivo se ha subido correctamente.";
} else {
    echo "Error al mover el archivo.";
}

Lenguaje del código: PHP (php)

Este código mueve el archivo desde su ubicación temporal en el servidor a un directorio llamado “uploads” y conserva su nombre original.

Con estos pasos, podrás procesar y validar archivos subidos en PHP utilizando la superglobal $_FILES.

A continuación, aprenderemos cómo trabajar con múltiples archivos y aplicar medidas de seguridad en la subida y manejo de archivos.

Subida y manejo de múltiples archivos

En algunas situaciones, es posible que desees permitir que los usuarios suban varios archivos a la vez. A continuación, se explica cómo modificar el formulario HTML y el script PHP para manejar múltiples archivos.

Atributo multiple en el campo input type="file"

Para permitir la selección de varios archivos en el formulario, debes agregar el atributo multiple al campo input type="file".

Además, el atributo name debe incluir corchetes [] al final para indicar que se trata de un array.

Por ejemplo:


<form action="subir_multiples.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="misArchivos[]" multiple>
  <button type="submit">Subir archivos</button>
</form>

Lenguaje del código: HTML, XML (xml)

Procesamiento y validación de múltiples archivos en PHP

En el script PHP, puedes acceder a la información de los archivos subidos a través de la superglobal $_FILES. Para manejar múltiples archivos, debes utilizar un bucle para procesar y validar cada archivo individualmente.

Por ejemplo, en el archivo “subir_multiples.php”:


// Verificar si se subieron archivos
if (isset($_FILES['misArchivos'])) {
    // Recorrer y procesar cada archivo
    for ($i = 0; $i < count($_FILES['misArchivos']['name']); $i++) {
        $nombre = $_FILES['misArchivos']['name'][$i];
        $tipo = $_FILES['misArchivos']['type'][$i];
        $tamano = $_FILES['misArchivos']['size'][$i];
        $temporal = $_FILES['misArchivos']['tmp_name'][$i];
        $error = $_FILES['misArchivos']['error'][$i];

        // Validar y mover el archivo (similar al ejemplo anterior)
    }
}

Lenguaje del código: PHP (php)

Con este enfoque, podrás procesar y validar múltiples archivos subidos utilizando la superglobal $_FILES en PHP. Recuerda aplicar las mismas validaciones y medidas de seguridad que se mencionaron en los puntos anteriores para garantizar que tu aplicación maneje la subida de archivos de manera eficiente y segura.

Seguridad en la subida y manejo de archivos

Al permitir la subida de archivos en tu aplicación web, es fundamental garantizar la seguridad tanto del servidor como de los usuarios. A continuación, se presentan algunas medidas de seguridad que puedes aplicar al procesar y manejar archivos subidos con PHP.

Validar el tipo de archivo real (MIME type)

Además de verificar el tipo de archivo mediante el valor enviado por el navegador en $_FILES['miArchivo']['type'], debes validar el tipo real del archivo.

Puedes hacer esto utilizando la función finfo_file().

Por ejemplo:


// Crear un objeto finfo para verificar el tipo MIME real del archivo
$finfo = new finfo(FILEINFO_MIME_TYPE);

// Obtener el tipo MIME real
$tipoReal = $finfo->file($_FILES['miArchivo']['tmp_name']);

// Verificar si el tipo MIME real está permitido
if (in_array($tipoReal, $tiposPermitidos)) {
    // Procesar el archivo
} else {
    echo "El archivo no cumple con los requisitos de tipo.";
}

Lenguaje del código: PHP (php)

Generar un nombre de archivo único

Para evitar la sobreescritura de archivos existentes y proteger la privacidad de los usuarios, puedes generar un nombre de archivo único para cada archivo subido. Puedes hacer esto utilizando la función uniqid().

Por ejemplo:


// Generar un nombre de archivo único
$extension = pathinfo($_FILES['miArchivo']['name'], PATHINFO_EXTENSION);
$nombreUnico = uniqid() . '.' . $extension;

// Mover el archivo a su ubicación final
$ubicacionFinal = $directorioDestino . $nombreUnico;

Lenguaje del código: PHP (php)

Limitar el acceso a los archivos subidos

Para evitar el acceso no autorizado a los archivos subidos, puedes almacenarlos en una carpeta protegida fuera del directorio web público o utilizar un archivo “.htaccess” para restringir el acceso a la carpeta de archivos subidos.

Por ejemplo, en un archivo “.htaccess”:


Deny from all

Lenguaje del código: CSS (css)

Protegerse contra ataques de carga de archivos

Para proteger tu aplicación web contra ataques de carga de archivos, puedes aplicar medidas adicionales como:

  • Verificar la autenticación y autorización de los usuarios antes de permitir la subida de archivos.
  • Aplicar límites de tamaño y número de archivos subidos para prevenir la saturación del servidor.
  • Utilizar un servicio de análisis de malware para escanear los archivos subidos en busca de amenazas.

Al aplicar estas medidas de seguridad, podrás garantizar que tu aplicación maneje la subida y el manejo de archivos de manera segura y eficiente, protegiendo tanto a tu servidor como a tus usuarios.

Ejemplos prácticos de uso de $_FILES en PHP

A continuación, se presentan dos ejemplos prácticos de uso de la superglobal $_FILES en PHP. Estos ejemplos ilustran cómo aplicar las técnicas y medidas de seguridad discutidas en los puntos anteriores.

Crear una galería de imágenes

Supongamos que deseas crear una galería de imágenes donde los usuarios puedan subir y ver fotos. Primero, crea un formulario HTML para la subida de imágenes:


<!-- formulario.html -->

<form action="galeria.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="imagen">
  <button type="submit">Subir imagen</button>
</form>

Lenguaje del código: HTML, XML (xml)

A continuación, crea el script PHP “galeria.php” para procesar y validar las imágenes subidas:


// galeria.php

// Configuración
$directorioDestino = 'imagenes/';
$tamanoMaximo = 2 * 1024 * 1024;
$tiposPermitidos = ['image/jpeg', 'image/png'];

// Procesar imagen subida
if (isset($_FILES['imagen']) && $_FILES['imagen']['error'] == 0) {
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $tipoReal = $finfo->file($_FILES['imagen']['tmp_name']);

    if ($_FILES['imagen']['size'] <= $tamanoMaximo && in_array($tipoReal, $tiposPermitidos)) {
        $extension = pathinfo($_FILES['imagen']['name'], PATHINFO_EXTENSION);
        $nombreUnico = uniqid() . '.' . $extension;
        $ubicacionFinal = $directorioDestino . $nombreUnico;

        if (move_uploaded_file($_FILES['imagen']['tmp_name'], $ubicacionFinal)) {
            echo "La imagen se ha subido correctamente.";
        } else {
            echo "Error al mover la imagen.";
        }
    } else {
        echo "La imagen no cumple con los requisitos de tamaño o tipo.";
    }
} else {
    echo "Error al subir la imagen.";
}

Lenguaje del código: PHP (php)

Finalmente, crea un script PHP para mostrar las imágenes en la galería:


// mostrar_galeria.php

$imagenes = glob('imagenes/*.{jpg,png}', GLOB_BRACE);

foreach ($imagenes as $imagen) {
    echo '<img src="' . $imagen . '" alt="Imagen" width="200">';
}

Lenguaje del código: PHP (php)

Crear un sistema de subida de archivos para documentos

Supongamos que deseas crear un sistema donde los usuarios puedan subir y descargar documentos (PDF y DOCX). Primero, crea un formulario HTML para la subida de documentos:


<!-- formulario.html -->

<form action="documentos.php" method="POST" enctype="multipart/form-data">
  <input type="file" name="documento">
  <button type="submit">Subir documento</button>
</form>

Lenguaje del código: HTML, XML (xml)

A continuación, crea el script PHP “documentos.php” para procesar y validar los documentos subidos:


// documentos.php

// Configuración
$directorioDestino = 'documentos/';
$tamanoMaximo = 10 * 1024 * 1024;
$tiposPermitidos = ['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];

// Procesar documento subido
if (isset($_FILES['documento']) && $_FILES['documento']['error'] == 0) {
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $tipoReal = $finfo->file($_FILES['documento']['tmp_name']);

    if ($_FILES['documento']['size'] <= $tamanoMaximo && in_array($tipoReal, $tiposPermitidos)) {
        $extension = pathinfo($_FILES['documento']['name'], PATHINFO_EXTENSION);
        $nombreUnico = uniqid() . '.' . $extension;
        $ubicacionFinal = $directorioDestino . $nombreUnico;

        if (move_uploaded_file($_FILES['documento']['tmp_name'], $ubicacionFinal)) {
            echo "El documento se ha subido correctamente.";
        } else {
            echo "Error al mover el documento.";
        }
    } else {
        echo "El documento no cumple con los requisitos de tamaño o tipo.";
    }
} else {
    echo "Error al subir el documento.";
}

Lenguaje del código: PHP (php)

Finalmente, crea un script PHP para mostrar la lista de documentos disponibles para descargar:


// mostrar_documentos.php

$documentos = glob('documentos/*.{pdf,docx}', GLOB_BRACE);

echo "<ul>";
foreach ($documentos as $documento) {
    $nombreDocumento = basename($documento);
    echo '<li><a href="' . $documento . '">' . $nombreDocumento . '</a></li>';
}
echo "</ul>";

Lenguaje del código: PHP (php)

Estos ejemplos prácticos demuestran cómo aplicar las técnicas y medidas de seguridad discutidas en los puntos anteriores al utilizar la superglobal $_FILES en PHP.

Puedes adaptar estos ejemplos a tus propias necesidades y requisitos para crear aplicaciones web seguras y eficientes que permitan la subida y el manejo de archivos.

Referencias

Aquí tienes algunas referencias útiles relacionadas con el tema de $_FILES y la subida de archivos en PHP:

  1. Documentación oficial de PHP – Subida de archivos mediante formularios POST.
  2. Documentación oficial de PHP – La superglobal $_FILES.
  3. Documentación oficial de PHP – finfo.
  4. Documentación oficial de PHP – move_uploaded_file.
  5. Documentación oficial de PHP – pathinfo.
  6. W3Schools – PHP File Upload.
  7. OWASP – Unrestricted File Upload.

Estas referencias te proporcionarán información adicional y en profundidad sobre la subida y el manejo de archivos en PHP utilizando la superglobal $_FILES, así como prácticas de seguridad y técnicas de validación.