Comunidad de diseño web y desarrollo en internet online

Subir multiples archivos con php

A veces queremos subir archivos al servidor usando http a través de un formulario, normalmente creamos un campo tipo file y listo, pero en ocasiones queremos subir múltiples archivos, como es el caso de los archivos adjuntos de los mail, es hay donde un solo campo se nos hace ineficiente y engorroso, pues requiere que se envide de uno en uno los archivos, podríamos simplemente crear unos 5 campos file pero, que tal si el usuario quiere subir mas o menos archivos? estaríamos fosando al usuario a recargar la pagina varias veces, o desperdiciaríamos espacio, en cada caso respectivamente. Una solución elegante es la que vemos en el método de adjuntar archivos de gmail, que dando click en un enlace nos crea un nuevo campo file listo para adjuntar un nuevo archivo, esto se puede lograr usando javascript, y procesando con php lo recibido por el servidor. A continuación veremos un aproximación de como lograr resultados similares:

Primero veamos el html del formulario, sencillo solo lo necesario para subir archivos:

Código :

 <form name="formu" id="formu" action="upload.php" method="post" enctype="multipart/form-data">
     <dl>            
   <dt><label>Archivos a Subir:</label></dt>
        <!-- Esta div contendrá todos los campos file que creemos -->
   <dd><div id="adjuntos">
        <!-- Hay que prestar atención a esto, el nombre de este campo debe siempre terminar en []
        como un vector, y ademas debe coincidir con el nombre que se da a los campos nuevos 
        en el script -->
   <input type="file" name="archivos[]" /><br />
   </div></dd>
   <dt><a href="#" onClick="addCampo()">Subir otro archivo</a></dt>      
   <dd><input type="submit" value="Enviar" id="envia" name="envia" /></dd>
     </dl>
</form>

Ahora vamos con el javascript, este es el corazón de este truco, y se encarga de crear los campos dinamicos:

Código :

<script type="text/javascript">
var numero = 0; //Esta es una variable de control para mantener nombres
            //diferentes de cada campo creado dinamicamente.
evento = function (evt) { //esta funcion nos devuelve el tipo de evento disparado
   return (!evt) ? event : evt;
}

//Aqui se hace lamagia... jejeje, esta funcion crea dinamicamente los nuevos campos file
addCampo = function () { 
//Creamos un nuevo div para que contenga el nuevo campo
   nDiv = document.createElement('div');
//con esto se establece la clase de la div
   nDiv.className = 'archivo';
//este es el id de la div, aqui la utilidad de la variable numero
//nos permite darle un id unico
   nDiv.id = 'file' + (++numero);
//creamos el input para el formulario:
   nCampo = document.createElement('input');
//le damos un nombre, es importante que lo nombren como vector, pues todos los campos
//compartiran el nombre en un arreglo, asi es mas facil procesar posteriormente con php
   nCampo.name = 'archivos[]';
//Establecemos el tipo de campo
   nCampo.type = 'file';
//Ahora creamos un link para poder eliminar un campo que ya no deseemos
   a = document.createElement('a');
//El link debe tener el mismo nombre de la div padre, para efectos de localizarla y eliminarla
   a.name = nDiv.id;
//Este link no debe ir a ningun lado
   a.href = '#';
//Establecemos que dispare esta funcion en click
   a.onclick = elimCamp;
//Con esto ponemos el texto del link
   a.innerHTML = 'Eliminar';
//Bien es el momento de integrar lo que hemos creado al documento,
//primero usamos la función appendChild para adicionar el campo file nuevo
   nDiv.appendChild(nCampo);
//Adicionamos el Link
   nDiv.appendChild(a);
//Ahora si recuerdan, en el html hay una div cuyo id es 'adjuntos', bien
//con esta función obtenemos una referencia a ella para usar de nuevo appendChild
//y adicionar la div que hemos creado, la cual contiene el campo file con su link de eliminación:
   container = document.getElementById('adjuntos');
   container.appendChild(nDiv);
}
//con esta función eliminamos el campo cuyo link de eliminación sea presionado
elimCamp = function (evt){
   evt = evento(evt);
   nCampo = rObj(evt);
   div = document.getElementById(nCampo.name);
   div.parentNode.removeChild(div);
}
//con esta función recuperamos una instancia del objeto que disparo el evento
rObj = function (evt) { 
   return evt.srcElement ?  evt.srcElement : evt.target;
}
</script>

Y por ultimo tenemos la contraparte php (upload.php, el destino del formulario), que se encargara de procesar lo que enviemos al servidor, este es solo un pequeño ejemplo de como operar los archivos y hacer lo que necesiten con ellos:

Código :

<?php 
   //Preguntamos si nuetro arreglo 'archivos' fue definido
         if (isset ($_FILES["archivos"])) {
         //de se asi, para procesar los archivos subidos al servidor solo debemos recorrerlo
         //obtenemos la cantidad de elementos que tiene el arreglo archivos
         $tot = count($_FILES["archivos"]["name"]);
         //este for recorre el arreglo
         for ($i = 0; $i < $tot; $i++){
         //con el indice $i, poemos obtener la propiedad que desemos de cada archivo
         //para trabajar con este
            $tmp_name = $_FILES["archivos"]["tmp_name"][$i];
            $name = $_FILES["archivos"]["name"][$i];
            echo("<b>Archivo </b> $key ");
            echo("<br />");
            echo("<b>el nombre original:</b> ");
            echo($name);
            echo("<br />");
            echo("<b>el nombre temporal:</b> \n");
            echo($tmp_name);
            echo("<br />");            
            }
      }      
?>


Bien con esto es suficiente para que creen los campos dinámicos de upload y los procesen en su servidor, esto es útil cuando no sabemos cuantos serán (como en gmail, jejeje), y otras muchas ocasiones donde necesitamos crear campos dinámicamente. Saludos

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro

Entra al foro y participa en la discusión

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate