I have the problem of wanting to make PHP receive all the files that were selected in the different file inputs that are generated dynamically with JavaScript. I would like to know if there is a way to send multiple files of different inputs to PHP via AJAX and then treat each file in PHP in some way.
What I have tried is the following:
HTML
<div class="contenedor__examen">
<div class="contenedor__examen__seccion">
<p>Nombre de la Pregunta</p>
<input type="text" class="inputTexto nombrePregunta">
<p>Respuesta Correcta</p>
<input type="text" class="inputTexto respuestaCorrecta">
<div class="contenedor__audio">
<input type="file" id="real-file" hidden="hidden" name="audio" class="botonAudio">
<button type="button" id="custom-button" class="botonInput" numinput="1">Subir Audio</button>
<br>
<span id="custom-text" class="textoInput">Ningún audio seleccionado</span>
</div>
<p>Texto al Reproducir</p>
<input type="text" class="inputTexto inputFinal textoAlReproducir">
</div>
</div>
The code block above is generated multiple times with a few differences added through JS.
JS
valoresAudios = [];
obtenerAudios = () => {
valoresAudios = [];
let audios = document.querySelectorAll(".botonAudio");
audios.forEach((_elemento, indice) => {
valor = audios[indice];
valoresAudios.push(valor);
});
};
btnEnviarExamen.addEventListener("click", (e) => {
e.preventDefault();
let nombreDelExamen = nombreExamen.value;
let temarioAlQuePertenece = valueSelect;
let enviarExamen = new FormData();
enviarExamen.append("nombreExamen", nombreDelExamen);
enviarExamen.append("temarioAlQuePertenece", temarioAlQuePertenece);
enviarExamen.append(
"valorNombrePreguntas",
JSON.stringify(valoresNombresPreguntas)
);
enviarExamen.append(
"valoresRespuestasCorrectas",
JSON.stringify(valoresRespuestasCorrectas)
);
enviarExamen.append("valoresAudios", valoresAudios);
enviarExamen.append(
"revaloresTextoAlReproducirspuestas",
JSON.stringify(valoresTextoAlReproducir)
);
xhr = new XMLHttpRequest();
xhr.open("POST", "/src/admin/examenes/subirExamen.php", true);
xhr.onload = function () {
if (this.status === 200) {
console.log(this.responseText);
}
};
xhr.send(enviarExamen);
});
There is more JS code but I don't think it's relevant, my problem is to send all the file inputs via AJAX to PHP in order to upload them to the server and store their location in MYSQL.
PHP
<?php
session_start();
require_once($_SERVER["DOCUMENT_ROOT"] . "/src/admin/comprobarAdmin.php");
require_once($_SERVER["DOCUMENT_ROOT"] . "/src/conexionbd.php");
$valoresAudio = $_POST["valoresAudios"];
for ($i = 0; $i < count($valoresAudio); $i++)
{
var_dump($_FILES["audio"]['name']);
}
Any help or suggestion is welcome. Thanks in advance.
You can reach the input files by the class
botonAudio
withquerySelectorAll()
and then iterate through each input to include the files in the FormData object.It would be more or less like this. For the proof of concept I have linked the action to the button click. Something curious in your code is that the inputs are hidden, so it is not understood how files can be selected from them? (I have removed the hidden property to be able to test).
Another thing is that you take care that entries with the same id are not created.
Perhaps this could be simpler if you used a form. When you request FormData from a form, it puts all the elements with tag inside
name
. The only problem is that for input of type file it doesn't check if they are empty or not. If this validation is important to you you can do it in several ways (I don't get into that because it deviates from the purpose of the question).With a form the code would look something like this, this is the basic example from MDN , which also explains how to add additional data to the FormData.
Whichever method you choose, it's a matter of passing the object
formData
to the Ajax request and retrieving the data from the server in the proper way.I hope it is useful to you.
Many thanks to @A.Cedano for all the help, since he guided me a lot to find the solution.
To send multiple files by AJAX to PHP you have to access each one of them, for example:
Then, to send them you have to add them to the
FormData()
, here is an example:The key to be able to receive multiple files in PHP is to name the key (forgive the redundancy) that we are going to send with two brackets, for example:
audio[]
, in addition, the value of the key must be the name of the array that we are going through but adding.files[0]
, example:audio.files[0]
. That's why when I tried withaudio.files[indice]
it it didn't work because the index has to be 0.To go through the data of the files sent to PHP, I recommend sending the number of files by POST, example:
In PHP to treat the files we perform a cycle
for
a$_FILES
and access each value of the array with their respective index names:name
,tmp_name
, etc and specifying the index of the value we want to access, here is an example:It is not complicated at all to send multiple files by AJAX, I totally recommend it instead of using the forms since we can also send other data in arrays to PHP.