PHP cURL调用API报HTTP 411错误:请求需分块或含Content-Length
解决PHP cURL POST请求返回HTTP 411错误的问题
问题分析
HTTP 411错误意味着服务器要求请求必须包含Content-Length头,或是使用分块编码传输数据。Postman会自动处理请求头的生成(包括Content-Length),但你的PHP cURL代码存在两个核心问题导致报错:
- 使用
CURLOPT_CUSTOMREQUEST => 'POST'会绕过cURL内置的POST请求处理逻辑,导致cURL不会自动计算并添加Content-Length头 - 手动添加
Content-Length时,可能存在计算方式错误(比如未正确计算JSON字符串的字节长度)
解决方案
方案1:让cURL自动处理请求头(推荐)
移除CURLOPT_CUSTOMREQUEST,改用CURLOPT_POST => true,同时通过数组转JSON的方式生成请求数据(避免手动编写JSON的语法错误)。cURL会自动计算Content-Length并添加到请求头:
<?php // 先定义数组,再转成JSON,避免手动写JSON的语法错误 $data = [ "TokenKey" => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "EmployeeList" => [ [ "Example1" => "1", "Example2" => "somedata2", "Example3" => "somedata3", "Example4" => "somedata4", "Example5" => "somedata5", "Example6" => "somedata6", "Example7" => "somedata7", "Example8" => "somedata8", "Example9" => "somedata9", "Example10" => "somedata10", "Example11" => "somedata11", "Example12" => "somedata12", "Example13" => "somedata13", "Example14" => "somedata14", "Example15" => "somedata15", "Example16" => "somedata16", "Example17" => "somedata17", "Example18" => "somedata18", "Example19" => "somedata19", "Example20" => "somedata20", "Example21" => "somedata21", "Example22" => "somedata22", "Example23" => "somedata23", "Example24" => "somedata24", "Example25" => "somedata25", "Example26" => "somedata26", "Example27" => "somedata27", "Example28" => "somedata28", "Example29" => "somedata29", "Example30" => "somedata30", "Example31" => "somedata31", "Example32" => null, "Example33" => null, "Example34" => null, "Example35" => "2022-12-06 22:05:22", "Example36" => false, "Example37" => true ] ] ]; $jsonData = json_encode($data); $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => 'https://xxx.xxx/xxx/xxx/xxx', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_POST => true, // 改用CURLOPT_POST触发自动处理逻辑 CURLOPT_POSTFIELDS => $jsonData, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ], ]); $response = curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); // 新增:获取HTTP状态码 curl_close($curl); echo $response; echo "<br>"; echo $statusCode; ?>
方案2:手动添加正确的Content-Length头
如果坚持使用CURLOPT_CUSTOMREQUEST,需要手动计算JSON字符串的字节长度,并添加Content-Length请求头:
<?php $jsonData = '{ "TokenKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "EmployeeList": [ { "Example1": "1", "Example2": "somedata2", "Example3": "somedata3", "Example4": "somedata4", "Example5": "somedata5", "Example6": "somedata6", "Example7": "somedata7", "Example8": "somedata8", "Example9": "somedata9", "Example10": "somedata10", "Example11": "somedata11", "Example12": "somedata12", "Example13": "somedata13", "Example14": "somedata14", "Example15": "somedata15", "Example16": "somedata16", "Example17": "somedata17", "Example18": "somedata18", "Example19": "somedata19", "Example20": "somedata20", "Example21": "somedata21", "Example22": "somedata22", "Example23": "somedata23", "Example24": "somedata24", "Example25": "somedata25", "Example26": "somedata26", "Example27": "somedata27", "Example28": "somedata28", "Example29": "somedata29", "Example30": "somedata30", "Example31": "somedata31", "Example32": null, "Example33": null, "Example34": null, "Example35": "2022-12-06 22:05:22", "Example36": false, "Example37": true } ] }'; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => 'https://xxx.xxx/xxx/xxx/xxx', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_POSTFIELDS => $jsonData, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Content-Length: ' . strlen($jsonData) // 计算JSON字符串的字节长度 ], ]); $response = curl_exec($curl); $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); // 新增:获取HTTP状态码 curl_close($curl); echo $response; echo "<br>"; echo $statusCode; ?>
关键注意点
- 用
json_encode生成JSON比手动编写更可靠,能避免逗号、引号遗漏等语法错误 strlen计算的是字符串的字节数,适配json_encode默认输出的UTF-8编码JSON- 原代码中
$statusCode未定义,需调用curl_getinfo才能获取HTTP状态码
内容的提问来源于stack exchange,提问作者isthemi
相关产品推荐
相关产品推荐

