J'utilise le code de réponse accepté (code de Felipe) depuis un certain temps et cela fonctionne très bien (merci, Felipe!).
Cependant, récemment, j'ai découvert qu'il avait des problèmes avec des objets ou des tableaux vides. Par exemple, lors de la soumission de cet objet:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP ne semble pas du tout voir B et C. Il obtient ceci:
[
"A" => "1",
"B" => "2"
]
Un regard sur la demande réelle dans Chrome montre ceci:
A: 1
:
D: 2
J'ai écrit un extrait de code alternatif. Il semble bien fonctionner avec mes cas d'utilisation, mais je ne l'ai pas testé de manière approfondie, donc utilisez-le avec prudence.
J'ai utilisé TypeScript parce que j'aime le typage fort mais il serait facile de le convertir en JS pur:
angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) {
// Use x-www-form-urlencoded Content-Type
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
function phpize(obj: Object | any[], depth: number = 1): string[] {
var arr: string[] = [ ];
angular.forEach(obj, (value: any, key: string) => {
if (angular.isObject(value) || angular.isArray(value)) {
var arrInner: string[] = phpize(value, depth + 1);
var tmpKey: string;
var encodedKey = encodeURIComponent(key);
if (depth == 1) tmpKey = encodedKey;
else tmpKey = `[${encodedKey}]`;
if (arrInner.length == 0) {
arr.push(`${tmpKey}=`);
}
else {
arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
}
}
else {
var encodedKey = encodeURIComponent(key);
var encodedValue;
if (angular.isUndefined(value) || value === null) encodedValue = "";
else encodedValue = encodeURIComponent(value);
if (depth == 1) {
arr.push(`${encodedKey}=${encodedValue}`);
}
else {
arr.push(`[${encodedKey}]=${encodedValue}`);
}
}
});
return arr;
}
// Override $http service's default transformRequest
(<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
if (!angular.isObject(data) || data.toString() == "[object File]") return data;
return phpize(data).join("&");
} ];
} ]);
Il est moins efficace que le code de Felipe mais je ne pense pas que cela ait beaucoup d'importance car il devrait être immédiat par rapport à la surcharge globale de la requête HTTP elle-même.
Maintenant PHP montre:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
Pour autant que je sache, il n'est pas possible d'obtenir PHP pour reconnaître que Ba et C sont des tableaux vides, mais au moins les clés apparaissent, ce qui est important lorsqu'il y a du code qui s'appuie sur une certaine structure même lorsqu'il est essentiellement vide à l'intérieur.
Notez également qu'il convertit les s non définis et les s null en chaînes vides.