ฉันใช้รหัสคำตอบที่ยอมรับ (รหัสของ Felipe) มาระยะหนึ่งแล้วและมันก็ใช้งานได้ดีมาก (ขอบคุณ Felipe!)
อย่างไรก็ตามเมื่อเร็ว ๆ นี้ฉันค้นพบว่ามีปัญหากับวัตถุหรืออาร์เรย์ที่ว่างเปล่า ตัวอย่างเช่นเมื่อส่งวัตถุนี้:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP ดูเหมือนจะไม่เห็น B และ C เลย มันได้รับสิ่งนี้:
[
"A" => "1",
"B" => "2"
]
ดูคำขอจริงใน Chrome จะแสดงสิ่งนี้:
A: 1
:
D: 2
ฉันเขียนตัวอย่างรหัสทางเลือก ดูเหมือนว่าจะทำงานได้ดีกับกรณีใช้งานของฉัน แต่ฉันยังไม่ได้ทดสอบอย่างกว้างขวางดังนั้นควรใช้ด้วยความระมัดระวัง
ฉันใช้ TypeScript เพราะฉันชอบการพิมพ์ที่แข็งแกร่ง แต่มันง่ายที่จะแปลงเป็น JS บริสุทธิ์
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("&");
} ];
} ]);
มันมีประสิทธิภาพน้อยกว่าโค้ดของ Felipe แต่ฉันไม่คิดว่ามันจะสำคัญมากเพราะมันควรจะถูกเปรียบเทียบกับค่าใช้จ่ายโดยรวมของคำขอ HTTP เอง
ตอนนี้ PHP แสดง:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
เท่าที่ฉันรู้ว่ามันเป็นไปไม่ได้ที่ PHP จะรับรู้ว่า Ba และ C เป็นอาร์เรย์ที่ว่างเปล่า แต่อย่างน้อยคีย์ก็ปรากฏขึ้นซึ่งเป็นสิ่งสำคัญเมื่อมีโค้ดที่ต้องอาศัยโครงสร้างบางอย่างแม้ว่ามันจะว่างเปล่า
นอกจากนี้โปรดทราบว่ามันจะแปลงs และnull ที่ไม่ได้กำหนดเป็นสตริงว่าง