Tôi đã sử dụng mã câu trả lời được chấp nhận (mã của Felipe) trong một thời gian và nó đã hoạt động rất tốt (cảm ơn, Felipe!).
Tuy nhiên, gần đây tôi phát hiện ra rằng nó có vấn đề với các đối tượng hoặc mảng trống. Ví dụ: khi gửi đối tượng này:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP dường như không thấy B và C nào cả. Nó nhận được điều này:
[
"A" => "1",
"B" => "2"
]
Nhìn vào yêu cầu thực tế trong Chrome cho thấy điều này:
A: 1
:
D: 2
Tôi đã viết một đoạn mã thay thế. Nó có vẻ hoạt động tốt với các trường hợp sử dụng của tôi nhưng tôi chưa thử nghiệm rộng rãi vì vậy hãy thận trọng khi sử dụng.
Tôi đã sử dụng TypeScript vì tôi thích gõ mạnh nhưng sẽ dễ dàng chuyển đổi sang JS thuần túy:
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("&");
} ];
} ]);
Nó kém hiệu quả hơn mã của Felipe nhưng tôi không nghĩ nó quan trọng lắm vì nó phải ngay lập tức so với tổng chi phí chung của chính yêu cầu HTTP.
Bây giờ PHP hiển thị:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
Theo như tôi biết thì không thể để PHP nhận ra rằng Ba và C là các mảng trống, nhưng ít nhất các khóa xuất hiện, điều này rất quan trọng khi có mã dựa trên một cấu trúc nhất định ngay cả khi bên trong nó trống rỗng.
Cũng lưu ý rằng nó chuyển đổi s và null s không xác định thành chuỗi rỗng.