PHP中使用CURLOPT发起PUT请求遇400错误求助
PHP CURL PUT请求400错误排查与解决
问题描述
使用PHP的CURLOPT发起PUT请求时遇到400错误,但DELETE和POST方法可正常运行。相关代码如下:
$url = 'https://theURL'; echo " \n URL:\n".$url." "; //The URL is correct $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); $headers[] = 'Content-length: 0'; //I don't have a body so the header is 0 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
不添加请求头时,会触发以下错误:
HTTP Error 411. The request must be chunked or have a content length.
设置Content-length: 0后,出现400错误:
REQUEST ERROR: The server encountered an error processing the request.
解决方法
方法1:用CURLOPT_PUT替代CURLOPT_CUSTOMREQUEST
当无请求体时,直接使用CURLOPT_PUT并设置空请求体,CURL会自动处理Content-Length:
$url = 'https://theURL'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_PUT, true); curl_setopt($ch, CURLOPT_POSTFIELDS, ''); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
方法2:改用分块传输编码
若服务器支持分块传输,添加Transfer-Encoding: chunked头替代Content-Length:
$url = 'https://theURL'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); $headers[] = 'Transfer-Encoding: chunked'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
方法3:发送符合格式的空请求体
部分服务器要求PUT请求携带格式合法的内容,可尝试发送空JSON体:
$url = 'https://theURL'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); $headers[] = 'Content-Type: application/json'; $headers[] = 'Content-Length: 2'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, '{}'); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
方法4:启用调试定位具体问题
添加调试选项,查看完整请求响应细节:
$url = 'https://theURL'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); $headers[] = 'Content-length: 0'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_VERBOSE, true); $verbose = fopen('php://temp', 'w+'); curl_setopt($ch, CURLOPT_STDERR, $verbose); $output = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); rewind($verbose); $verboseLog = stream_get_contents($verbose); echo "调试日志:\n" . $verboseLog; curl_close($ch);
内容的提问来源于stack exchange,提问作者titusala
相关产品推荐
相关产品推荐

