ajouter un tableau à FormData et envoyer via AJAX
j'utilise ajax pour soumettre un formulaire multipart avec tableau, champs de texte et fichiers.
j'ajoute chaque VAR aux données principales comme si
var attachments = document.getElementById('files');
var data= new FormData();
for (i=0; i< attachments.files.length; i++){
data.append('file', attachments.files[i]);
console.log(attachments.files[i]);
data.append ('headline', headline);
data.append ('article', article);
data.append ('arr', arr);
data.append ('tag', tag);
puis j'utilise la fonction ajax pour l'Envoyer à un fichier PHP pour stocker dans sql DB.
$.ajax({
type: "post",
url: 'php/submittionform.php',
cache: false,
processData: false,
contentType: false,
data: data,
success: function(request) {$('#box').html(request); }
})
mais du côté de PHP, la variable arr
, qui est un tableau apparaît comme une chaîne de caractères.
Quand Je ne l'envoie pas avec ajax comme données de forme mais utiliser le simple $.POST
option Je l'obtiens comme un tableau du côté de PHP, mais alors je ne peux pas envoyer les fichiers aussi bien.
des solutions?
5 réponses
vous avez plusieurs options:
convertissez-le en une chaîne JSON, puis analysez-le en PHP (recommandé)
JS
var json_arr = JSON.stringify(arr);
PHP
$arr = json_decode($_POST['arr']);
Ou utiliser @Curiosités de la méthode
envoie un tableau via FormData
.
Non recommandé: Sérialiser les données, puis désérialiser en PHP
JS
// Use <#> or any other delimiter you want
var serial_arr = arr.join("<#>");
PHP
$arr = explode("<#>", $_POST['arr']);
vous pouvez aussi envoyer un tableau via FormData
de cette façon:
var formData = new FormData;
var arr = ['this', 'is', 'an', 'array'];
for (var i = 0; i < arr.length; i++) {
formData.append('arr[]', arr[i]);
}
pour que vous puissiez écrire arr[]
de la même manière que vous le faites avec un simple formulaire HTML. En cas de PHP, ça devrait marcher.
, Vous pouvez trouver cet article utile: Comment passer un tableau dans une chaîne de requête?
C'est une vieille question mais j'ai rencontré ce problème avec l'affichage d'objets avec des fichiers récemment. J'avais besoin d'être capable de poster un objet, avec des propriétés d'enfant qui étaient des objets et des tableaux aussi bien.
la fonction ci-dessous va parcourir un objet et créer l'objet formData correct.
// formData - instance of FormData object
// data - object to post
function getFormData(formData, data, previousKey) {
if (data instanceof Object) {
Object.keys(data).forEach(key => {
const value = data[key];
if (value instanceof Object && !Array.isArray(value)) {
return this.getFormData(formData, value, key);
}
if (previousKey) {
key = `${previousKey}[${key}]`;
}
if (Array.isArray(value)) {
value.forEach(val => {
formData.append(`${key}[]`, val);
});
} else {
formData.append(key, value);
}
});
}
}
cela convertira le JSON suivant -
{
name: 'starwars',
year: 1977,
characters: {
good: ['luke', 'leia'],
bad: ['vader'],
},
}
dans le FormData suivant
name, starwars
year, 1977
characters[good][], luke
characters[good][], leia
characters[bad][], vader
version dactylographiée:
export class Utility {
public static convertModelToFormData(model: any, form: FormData = null, namespace = ''): FormData {
let formData = form || new FormData();
let formKey;
for (let propertyName in model) {
if (!model.hasOwnProperty(propertyName) || !model[propertyName]) continue;
let formKey = namespace ? `${namespace}[${propertyName}]` : propertyName;
if (model[propertyName] instanceof Date)
formData.append(formKey, model[propertyName].toISOString());
else if (model[propertyName] instanceof Array) {
model[propertyName].forEach((element, index) => {
const tempFormKey = `${formKey}[${index}]`;
this.convertModelToFormData(element, formData, tempFormKey);
});
}
else if (typeof model[propertyName] === 'object' && !(model[propertyName] instanceof File))
this.convertModelToFormData(model[propertyName], formData, formKey);
else
formData.append(formKey, model[propertyName].toString());
}
return formData;
}
}
utilisant:
let formData = Utility.convertModelToFormData(model);
version suivante valide pour les modèles contenant des arays de valeurs simples:
function convertModelToFormData(val, formData = new FormData(), namespace = '') {
if((typeof val !== 'undefined') && (val !== null)) {
if(val instanceof Date) {
formData.append(namespace, val.toISOString());
} else if(val instanceof Array) {
for(let element of val) {
convertModelToFormData(element, formData, namespace + '[]');
}
} else if(typeof val === 'object' && !(val instanceof File)) {
for (let propertyName in val) {
if(val.hasOwnProperty(propertyName)) {
convertModelToFormData(val[propertyName], formData, namespace ? namespace + '[' + propertyName + ']' : propertyName);
}
}
} else {
formData.append(namespace, val.toString());
}
}
return formData;
}