直接傳陣列給 CURLOPT_POSTFIELDS 導致 Content-Type: multipart/form-data,部分伺服器回傳 500。
$post_data = ['key1' => 'val1', 'key2' => 'val2']; // ❌ 錯誤:觸發 multipart/form-data curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // Header: Content-Type: multipart/form-data; boundary=----xxx // ✅ 正確:http_build_query 轉為 application/x-www-form-urlencoded curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); // Header: Content-Type: application/x-www-form-urlencoded
If value is an array, the Content-Type header will be set to multipart/form-data.
(值為陣列時,自動設為 multipart/form-data)
cURL 為了支援 @filename 檔案上傳語法,將陣列預設視為 multipart。但多數 API 僅需表單編碼。
function curl_post(string $url, array $data, array $options = []): string {
$ch = curl_init($url);
curl_setopt_array($ch, array_merge([
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
], $options));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
// 檔案上傳專用(需 CURLFile,PHP 5.5+)
$post = ['file' => new CURLFile('/path/to/file.png', 'image/png', 'filename.png')];
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); // 此時 multipart 正確
multipart:含 boundary 分隔符,體積較大urlencoded:標準表單編碼,體積小、相容性佳