HTML 表單提交陣列資料到 PHP 後端,再轉發至其他服務,是常見整合場景。本文系統說明:表單命名規則讓 PHP 接收陣列、序列化/反序列化在服務間傳遞陣列、Base64 編碼處理特殊字元,並提供完整代碼範例。
同名輸入元素的 name 屬性必須以 [] 結尾:
// receive.php $colors = $_POST['colors'] ?? []; // 陣列: ['red', 'green', 'blue'] var_dump($colors);
$_POST['user'] // ['name'=>'John', 'email'=>'john@example.com'] $_POST['products'] // [['id'=>'1','name'=>'商品A'], ['id'=>'2','name'=>'商品B']]
// 錯誤示範
$postData = http_build_query($_POST); // 陣列值會被轉為 "Array"
file_get_contents('https://service-b.com/api', false, stream_context_create([
'http' => ['method'=>'POST', 'header'=>'Content-Type: application/x-www-form-urlencoded', 'content'=>$postData]
]));
// 服務端 A:序列化特定陣列欄位
$_POST['colors'] = serialize($_POST['colors']);
// 現在 $_POST['colors'] 為字串: 'a:3:{i:0;s:3:"red";i:1;s:5:"green";i:2;s:4:"blue";}'
// 發送請求 (application/x-www-form-urlencoded)
$postData = http_build_query($_POST);
// ...
// 服務端 B:反序列化還原陣列
$colors = unserialize($_POST['colors']);
// 注意:若經過 URL 編碼,需先 urldecode() 或自動由 PHP 處理
// 服務端 A $_POST['colors_json'] = json_encode($_POST['colors']); // 發送... // 服務端 B $colors = json_decode($_POST['colors_json'], true); // true = 關聯陣列
// 服務端 A $serialized = serialize($_POST['colors']); $encoded = base64_encode($serialized); // 放入隱藏欄位或 POST 欄位 // // 服務端 B $received = $_POST['colors_data']; $decoded = base64_decode($received); $colors = unserialize($decoded);
$colors, 'timestamp' => time()]);
$ch = curl_init($apiUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);
echo 'API 回應: ' . $response;
?>
| 陷阱 | 解決方案 |
|---|---|
| 未加 [] 導致只收到最後一個值 | name="colors[]" 必加中括號 |
| serialize() 含特殊字元破壞 URL/表單 | base64_encode() 包裹 |
| unserialize() 不受信任資料導致物件注入 | 改用 json_decode(),或僅在可信內部服務間使用 |
| json_encode() 中文被轉 \uXXXX | 加 JSON_UNESCAPED_UNICODE 旗標 |
| http_build_query() 陣列值為陣列時產生 key[0]=val | 預設行為正確,PHP 接收端自動還原多維陣列 |
// 前端直接發送 JSON 到後端 API
fetch('/api/colors', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({colors: ['red', 'green', 'blue']})
}).then(r => r.json()).then(console.log);
現代 SPA/前後端分離架構下,前端直接發 JSON 給 API,後端 json_decode(file_get_contents('php://input'), true) 接收,完全繞過表單陣列命名與序列化問題。
PHP 接收表單陣列靠 name="field[]";服務間傳遞陣列推薦 JSON (json_encode/decode),跨語言相容、安全、可讀;舊系統相容可用 serialize + base64。現代架構建議前端直發 JSON,簡化後端處理邏輯。