En este blog te he enseñado cómo subir uno o varios archivos con HTML y PHP puro, así como subir un archivo con AJAX usando FormData.
Ahora te voy a enseñar cómo subir varios archivos (ilimitados o sin una longitud fija) usando JavaScript, AJAX, FormData y PHP.
En el caso de PHP no vamos a necesitar hacer muchas cosas, vamos a seguir leyendo de $_FILES
justo como cuando subíamos múltiples archivos de la manera normal.
<?php
/*
https://parzibyte.me/blog
*/$conteo = count($_FILES["archivos"]["name"]);
for ($i = 0; $i < $conteo; $i++) {
$ubicacionTemporal = $_FILES["archivos"]["tmp_name"][$i];
$nombreArchivo = $_FILES["archivos"]["name"][$i];
$extension = pathinfo($nombreArchivo, PATHINFO_EXTENSION);
// Renombrar archivo
$nuevoNombre = sprintf("%s_%d.%s", uniqid(), $i, $extension);
// Mover del temporal al directorio actual
move_uploaded_file($ubicacionTemporal, $nuevoNombre);
}
// Responder al cliente
echo json_encode(true);
Fíjate en que recorremos el arreglo de archivos, creamos un nuevo nombre (concatenando un id único obtenido con uniqid
y el índice del arreglo) y movemos el archivo desde la ubicación temporal a la ubicación del script.
El archivo se llama guardar.php
y al final imprimirá un true
como JSON indicando que toda la operación fue correcta. Ahora veamos el lado del cliente.
En el lado del cliente comencemos viendo el diseño HTML. Solo tenemos un div de estado (en donde vamos a mostrar mensajes), el campo para subir los archivos y el botón que hace la subida de archivos.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transferencia de archivos por AJAX</title>
<link rel="stylesheet" href="https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-12">
<h1>Transferir archivos</h1>
<a href="//parzibyte.me/blog"></a>
<div class="form-group">
<input multiple type="file" class="form-control" id="inputArchivos">
<br><br>
<button id="btnEnviar" class="btn btn-success">Enviar</button>
</div>
<div class="alert alert-info" id="estado"></div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Para obtener una referencia a los elementos usamos el id de cada uno. Por ahora tenemos inputArchivos
, estado
y btnEnviar
. Los obtenemos desde JavaScript y hacemos el envío con el siguiente código:
/*
https://parzibyte.me/blog
*/// Elementos del DOM
const $inputArchivos = document.querySelector("#inputArchivos"),
$btnEnviar = document.querySelector("#btnEnviar"),
$estado = document.querySelector("#estado");
$btnEnviar.addEventListener("click", async () => {
const archivosParaSubir = $inputArchivos.files;
if (archivosParaSubir.length <= 0) {
// Si no hay archivos, no continuamos
return;
}
// Preparamos el formdata
const formData = new FormData();
// Agregamos cada archivo a "archivos[]". Los corchetes son importantes
for (const archivo of archivosParaSubir) {
formData.append("archivos[]", archivo);
}
// Los enviamos
$estado.textContent = "Enviando archivos...";
const respuestaRaw = await fetch("./guardar.php", {
method: "POST",
body: formData,
});
const respuesta = respuestaRaw.json();
// Puedes manejar la respuesta como tú quieras
console.log({ respuesta });
// Finalmente limpiamos el campo
$inputArchivos.value = null;
$estado.textContent = "Archivos enviados";
});
Lo importante aquí es que obtenemos los archivos del input accediendo a su propiedad files
. Luego agregamos una entrada al formData por cada archivo que haya, pero fíjate en que lo estamos agregando a archivos[]
con todo y corchetes.
Finalmente enviamos el formData a guardar.php
usando fetch de JavaScript en la línea 22.
El código completo lo puedes encontrar en el repositorio de GitHub. Recuerda que si quieres ver lo básico puedes ver cómo subir un archivo a PHP, subir varios archivos usando solo PHP o subir un archivo con AJAX y PHP.
También puedes explorar más sobre PHP o JavaScript en mi blog.
Hoy te voy a presentar un creador de credenciales que acabo de programar y que…
Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…
En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…
En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…
Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…
En este artículo te voy a enseñar cómo usar un "top level await" esperando a…
Esta web usa cookies.
Ver comentarios
Si lo que quieren es que no cambie el nombre y lo guarde en una carpeta con este arregleo lo haces la variable $uploads_dir es el nombre de la carpeta.
<?php
$conteo = count($_FILES["archivos"]["name"]);
$uploads_dir = 'archivos';
for ($i = 0; $i
Perfecto amigo, realice tu ejemplo con algunos pequeños ajustes a codeigniter y me sube perfecto. Gracias por el apoyo de dejar libre tu codigo, en realidad fue de gran ayuda para mis ejemplos.
Para el chico que se queja con el nombre porque se le guarda con unos codigos, le respodo que actualemente la linea de codigo del nombre es esta: $nuevoNombre = sprintf("%s_%d.%s", uniqid(), $i, $extension);
Gracias por sus comentarios. Saludos!
Cree una carpeta files para guardar los archivos pero cuando los subo , se cambia el nombre del archivo. Ejemplo: subo un archivo ejemplo.pdf y se pone como unos códigos.
Y cuál es el problema?