enviar archivos al servidor usando PHP

Enviar un archivo al servidor con PHP

En este artículo, te voy a explicar como hacer para enviar un archivo al servidor con PHP. Además te comentaré algunos conceptos básicos para la carga de ficheros en PHP.

Y por ultimo, te dejaré un ejemplo completo para descargar y usar con todos los archivos necesarios y comentados.

Para que esto funcione vamos a necesitar construir un formulario en HTML, para seleccionar el fichero a enviar. Luego, en un archivo PHP crearemos la lógica de carga y gestión del archivo en el servidor. Y por ultimo, el manejo de los mensajes que mostraremos por pantalla en cada caso.

Formulario HTML para subir archivos

Voy 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. Y también de listar el directorio de destino y mostrar los archivos que hemos cargado.

Por otro lado, el archivo upload.php es responsable de cargar un archivo en el servidor y gestionar los mensajes que veremos por pantalla.

Además, en el ejemplo que te dejo para compartir, todos los ficheros que enviamos al servidor se almacenan en el directorio archivos_subidos, por lo que debes asegurarte de que esta carpeta exista y que tenga permisos de escritura.

En esta sección, veremos las partes clave del archivo index.php.

<div class="row">
    <form action="upload.php" method="post" enctype="multipart/form-data" id="import_form">
        <div class="col-6">
            <label for="file" class="form-label">Subir archivo al servidor</label>
            <input type="file" name="archivoSubir" class="form-control"/>
        </div>
        <div class="col-6 p-3">
            <input type="submit" class="btn btn-primary" name="btnSubir" id="btnSubir" value="ENVIAR ARCHIVO">
            <span id="cargando" style="visibility: hidden;"><img src='img/loading.gif' width='20px' height='20px'/> Procesando Archivo ...</span>
        </div>
    </form>
</div>

A simple vista, es un formulario típico, aunque hay una diferencia importante en el valor del atributo enctype de la etiqueta <form>. En este caso debe configurarse como  multipart/form-data ya que el formulario contiene un campo del tipo «archivo». 

El atributo enctype especifica el tipo de codificación que se debe usar cuando se envía el formulario, y puede tomar uno de los siguientes valores posibles:

  • application/x-www-form-urlencoded: este es el valor por defecto cuando no establece el valor del atributo enctype explícitamente. En este caso, los caracteres se codifican antes de que se envíen al servidor. Si no tienes el campo de tipo «archivo» en el formulario, debes usar este valor para el atributo enctype.
  • multipart/form-data: cuando se utiliza el valor multipart/form-data para el atributo enctype, 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.
Así funciona el ejemplo terminado

Manejo de los mensajes

Aparte de eso, hemos generado un mensaje en la parte superior del formulario. Este mensaje mostrará el estado de la carga luego de enviar el archivo al servidor.

Un poco mas adelante, dentro del script upload.php, veremos en detalle como manejar los mensajes y enviarlos dentro de una variable de sesión.

Un poco de CSS para la presentación

Dentro del <head> de nuestro archivo, haremos las llamadas necesarias para incorporar las librerías de Bootstrap y jQuery.

Este bloque no es necesario para el funcionamiento del ejemplo, pero los incluyo para tener, por un lado, los estilos de Bootstrap incluidos. Y por el otro, el funcionamiento de jQuery para los mensajes del estado de carga.

<!-- Incluir Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<!-- Incluir Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<!-- Incluir jQuery JS -->
<script src="https://code.jquery.com/jquery-3.7.0.min.js" integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

Mostrar el contenido del directorio

Finalmente, el ultimo bloque del archivo index,php, va a servir para mostrar el contenido del directorio de destino, con todos los ficheros que hemos enviado al servidor con PHP.

<div class="row">
    <div class="col-6">
        <h3>Contenido del directorio:</h3>

        <?php
            function listarArchivos( $path ){
                // Abro la carpeta que nos pasan como parámetro
                $dir = opendir($path);
                // Leo todos los ficheros de la carpeta
                while ($elemento = readdir($dir)){
                    // Evitamos los elementos . y .. que tienen todas las carpetas
                    if( $elemento != "." && $elemento != ".." && $elemento != "desktop.ini"){
                        // Si es una carpeta
                        if( is_dir($path.$elemento) ){
                            // Muestro la carpeta en negritas
                            echo "<strong>&lt;" . $elemento . "&gt;</strong><br>";
                        // Si es un fichero
                        } else {
                            // Muestro el fichero
                            echo $elemento ."<br>";
                        }
                    }
                }
            }
            // Llamamos a la función para que nos muestre el contenido de la carpeta archivos_subidos
            listarArchivos("./archivos_subidos/");
        ?>
    </div>
</div>

Para esto, nos serviremos de la funcion listarArchivos(«») a la que le pasaremos como parametro el nombre de la carpeta que queremos listar. En este ejemplo será la carpeta archivos_subidos

Dentro de listarArchivos() haremos uso de algunas funciones propias que nos ofrece PHP para el manejo de directorios:

  • opendir() Abre un manejador de directorio
  • readdir() Lee el contenido de un directorio
  • is_dir() Indica si el nombre de un elemento leído, es un directorio

Crear la lógica para enviar un archivo al servidor con PHP

En la sección anterior, creamos el formulario HTML que se muestra en el lado del cliente y te permite cargar un archivo desde tu computadora.

Ahora, veremos que hacer del lado del servidor para manejar el archivo cargado.

En el archivo upload.php, en primer lugar, debemos comprobar si se trata de una solicitud POST válida.

if (isset($_POST['btnSubir']) && $_POST['btnSubir'] == 'ENVIAR ARCHIVO')
{
...
}

En PHP, cuando se envía un archivo al servidor, la variable superglobal $_FILES se completa con toda la información sobre el archivo cargado. Se inicializa como un arreglo y puede contener la siguiente información:

  • tmp_name: En esta variable se almacena la ruta temporal donde se carga el archivo.
  • 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 constante UPLOAD_ERR_OK.

Después de validar la solicitud POST, verificamos que la carga del archivo se realizó correctamente. Si la carga del archivo es exitosa, inicializamos algunas variables con información sobre el archivo cargado.

if (isset($_FILES['archivoSubir']) && $_FILES['archivoSubir']['error'] === UPLOAD_ERR_OK)
  {
    // Obtengo los detalles del archivo
    $fileTmpPath = $_FILES['archivoSubir']['tmp_name'];
    $fileName = $_FILES['archivoSubir']['name'];
    $fileSize = $_FILES['archivoSubir']['size'];
    $fileType = $_FILES['archivoSubir']['type'];
    $fileNameCmps = explode(".", $fileName);
    $fileExtension = strtolower(end($fileNameCmps));
  ...
  }

En el fragmento anterior, también hemos identificado la extensión del archivo cargado y lo hemos almacenado en la variable $fileExtension

Es importante restringir el tipo de archivo que se puede cargar al servidor a ciertas extensiones. Lo hemos hecho al verificar la extensión del archivo cargado y compararlo con un conjunto de extensiones que hemos habilitado y almacenado en un array.

// Verificar ue el archivo corresponda con las extensiones permitidas
$allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'xlsx', 'doc', 'docx', 'pdf');

Mover el fichero subido a su ubicación definitiva

Finalmente, usamos la función move_uploaded_file para mover el archivo cargado a la ubicación específica de nuestra elección. En este ejemplo es la carpeta archivos_subidos

La función move_uploaded_file toma dos argumentos. El primer argumento es el nombre de archivo del fichero 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.

if(move_uploaded_file($fileTmpPath, $dest_path)) 
{
  $message ='success';
}
else 
{
  $message = 'error';
}

Como funciona todo junto

Al ejecutar el archivo index.php, debe mostrar el formulario de carga del archivo que se verá así:

enviar un archivo al servidor con PHP

Haz clic en el botón Seleccionar Archivo que debería abrir un cuadro de diálogo para poder seleccionar un archivo de tu ordenador. Seleccionas un archivo, que este dentro de las extensiones permitidas en el script, y luego haz clic en el botón ENVIAR ARCHIVO

Deberías enviar el formulario y, si todo va bien, deberías ver el nombre del archivo cargado en el la lista de abajo y también dentro del directorio archivos_subidos.

Gracias a la librería jQuery, luego de cada carga exitosa se mostrará un mensaje en color verde, avisándote que el fichero se subió con éxito.

También puedes intentar cargar otros archivos con extensiones que no están permitidas y verificar si nuestro script evita dichas cargas. en este caso, veras un mensaje en amarillo con el listado de extensiones permitidas.

Conclusión

Hoy te expliqué, en detalle, como hacer un script para enviar un archivo al servidor con PHP. Repasando las líneas mas importantes del formulario y la lógica de carga.

Finalmente, aprovecho para compartir el ejemplo completo, listo para descargar y usar, desde mi repositorio de GitHub. Contiene todos los archivos mencionados en el post, comentados en detalle para su mejor comprensión.

Todo el ejemplo está desarrollado sobre mi plantilla básica en HTML que compartí hace unas semanas. Lista para comenzar a modificar sin tener que lidiar con las configuraciones iniciales al momento de iniciar cualquier proyecto web.


Si te gustó o te entretuvo el contenido de este posteo, haciendo un click en los avisos me ayudas a mantener el sitio con vida y a seguir publicando.

Y si quieres ganar algo de dinero sin esfuerzo, registrate en Honeygain desde este banner y recibí 5 dolares de regalo al comenzar a usar la aplicación para generar ingresos pasivos.

HoneyGain

Acá puedes conocer más sobre ingresos pasivos, que es y como funciona HoneyGain.

Deja un comentario