PHP Curl请求在Postman外失效:含数组的formdata问题排查
问题:PHP cURL POST请求中
registration_attributes数组构建导致"Missing"错误 背景
我用以下PHP cURL代码发起POST请求,该请求在Postman中可正常运行,但在生产服务器上返回响应{"registration_attributes":["Missing"]}。请问我构建registration_attributes数组的方式是否存在错误?
原代码:
$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://www.sample.com/v2/clients?token=DMfJjzWLngIn0JBHA0gWcg", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => "------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"active_registration_id\" 123 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"language_id\" 79 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"archived\" {{archived}} ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"enabled\" {{enabled}} ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"password\" SamplePassword ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"password_confirmation\" SamplePassword ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[first_name]\" Justin ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[last_name]\" Trudeau ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[email]\" email@sample.com ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[telephone_1]\" 555-555-5555 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[date_of_birth]\" 1943-10-10 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[gender]\" Male ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[referral_code]\" Ample Clinic 123 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[status]\" Registration Pending ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"For Additional Permitted Parameters:\" See Registration Parameters ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[date_of_birth]\" 1943-10-10 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[gender]\" Male ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[referral_code]\" Ample Clinic 123 ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name=\"registration_attributes[status]\" Registration Pending ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; ", CURLOPT_HTTPHEADER => array( "Content-Type: application/x-www-form-urlencoded", "content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" ), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; }
问题分析与解决方案
你的代码里有几个关键问题导致服务器无法正确解析registration_attributes字段:
冲突的Content-Type头
你同时设置了application/x-www-form-urlencoded和multipart/form-data两种Content-Type,这会让服务器搞不清该用哪种格式解析请求体,直接导致表单数据解析失败。手动拼接multipart内容的错误
- 你手动构建的POST数据末尾有一段不完整的字段:
------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data;,没有完成字段定义,也没有正确的结束边界标记(正确的结束边界应该是------WebKitFormBoundary7MA4YWxkTrZu0gW--,末尾带两个减号)。 - 重复提交了
registration_attributes下的多个字段(比如date_of_birth、gender等),这也可能干扰服务器的解析逻辑。
- 你手动构建的POST数据末尾有一段不完整的字段:
手动构建multipart的不可靠性
手动拼接multipart/form-data格式很容易出错,比如换行符、边界字符串不一致、字段格式错误等,Postman会自动处理这些细节,所以能正常运行,但你的手动拼接版本有漏洞。
修正后的代码(推荐方案)
直接用PHP数组组织POST数据,让cURL自动处理multipart/form-data的格式和边界,这是最可靠的方式:
$curl = curl_init(); // 用数组整理所有POST参数,自动支持嵌套数组格式 $postData = [ 'active_registration_id' => 123, 'language_id' => 79, 'archived' => '{{archived}}', 'enabled' => '{{enabled}}', 'password' => 'SamplePassword', 'password_confirmation' => 'SamplePassword', 'registration_attributes' => [ 'first_name' => 'Justin', 'last_name' => 'Trudeau', 'email' => 'email@sample.com', 'telephone_1' => '555-555-5555', 'date_of_birth' => '1943-10-10', 'gender' => 'Male', 'referral_code' => 'Ample Clinic 123', 'status' => 'Registration Pending' ], 'For Additional Permitted Parameters:' => 'See Registration Parameters' ]; curl_setopt_array($curl, [ CURLOPT_URL => "https://www.sample.com/v2/clients?token=DMfJjzWLngIn0JBHA0gWcg", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", // 直接传入数组,cURL会自动生成正确的multipart/form-data格式 CURLOPT_POSTFIELDS => $postData, // 不需要手动设置Content-Type,cURL会自动添加正确的头信息 CURLOPT_HTTPHEADER => [] ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; }
关键修正点说明
- 用数组组织参数,嵌套的
registration_attributes数组会被cURL自动转换成正确的表单字段格式(比如registration_attributes[first_name])。 - 移除了冲突的Content-Type头,让cURL自动处理,避免格式混淆。
- 删除了重复的字段,确保请求体干净无歧义。
如果一定要手动构建multipart内容,务必确保:
- 所有边界字符串完全一致,结束边界必须带两个减号。
- 每个字段的格式正确,字段名和值之间有正确的换行。
- 只设置一个正确的Content-Type头。
内容的提问来源于stack exchange,提问作者Jeremy Giles
相关产品推荐
相关产品推荐

