PHP CURL PUT请求无法提交Payload数据问题求助
问题:PHP CURL PUT请求无法提交Payload数据,命令行curl正常
向API端点发送PUT请求提交JSON数据时,命令行curl可正常执行,但PHP CURL无法成功提交Payload数据。
命令行curl正常执行的命令
curl -v --insecure --request PUT --url <https://blabla/blablabla> --user 'username:password' --header 'Content-Type: application/json' --data '<valid json data>'
对应的PHP CURL代码(无法正常工作)
// get cURL resource $curl = curl_init(); // set cURL options $curloptions = array( CURLOPT_PUT => true, // set method to PUT CURLOPT_RETURNTRANSFER => true, // return the transfer as a string CURLOPT_VERBOSE => true, // output verbose information CURLOPT_SSL_VERIFYHOST => false, // ignore self signed certificates CURLOPT_SSL_VERIFYPEER => false, CURLOPT_USERNAME => $config['uag']['user'], // set username CURLOPT_PASSWORD => $config['uag']['pass'], // set password CURLOPT_HTTPHEADER => array( // set headers "Content-Type: application/json", ), CURLOPT_POSTFIELDS => $jsondata // set data to post / put ); curl_setopt_array($curl, $curloptions); foreach($serverurilist as $uri) { // set url curl_setopt($curl, CURLOPT_URL, $uri); // send the request and save response to $response $response = curl_exec($curl); // stop if fails if(!$response) { die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl)); } var_dump($response); } // close curl resource to free up system resources curl_close($curl);
抓包对比发现的差异
通过tcpdump抓包无加密请求后发现:
- 命令行curl发送
Expect: 100-continue请求,收到服务器返回HTTP/1.1 100 Continue响应后,立即提交数据 - PHP CURL收到该响应后无任何动作,直至超时退出
解决方案
问题核心是**CURLOPT_PUT与CURLOPT_POSTFIELDS的冲突**:当CURLOPT_PUT设为true时,PHP CURL会默认使用CURLOPT_INFILE读取PUT数据,直接忽略CURLOPT_POSTFIELDS的内容。
修正步骤
- 移除
CURLOPT_PUT => true配置 - 改用
CURLOPT_CUSTOMREQUEST => 'PUT'指定请求方法,保留CURLOPT_POSTFIELDS传递JSON数据
修正后的PHP代码
// get cURL resource $curl = curl_init(); // set cURL options $curloptions = array( CURLOPT_CUSTOMREQUEST => 'PUT', // 指定PUT请求方法 CURLOPT_RETURNTRANSFER => true, // return the transfer as a string CURLOPT_VERBOSE => true, // output verbose information CURLOPT_SSL_VERIFYHOST => false, // ignore self signed certificates CURLOPT_SSL_VERIFYPEER => false, CURLOPT_USERNAME => $config['uag']['user'], // set username CURLOPT_PASSWORD => $config['uag']['pass'], // set password CURLOPT_HTTPHEADER => array( // set headers "Content-Type: application/json", "Expect:" // 禁用Expect:100-continue,避免服务器响应异常导致超时 ), CURLOPT_POSTFIELDS => $jsondata // 传递PUT请求的JSON数据 ); curl_setopt_array($curl, $curloptions); foreach($serverurilist as $uri) { // set url curl_setopt($curl, CURLOPT_URL, $uri); // send the request and save response to $response $response = curl_exec($curl); // stop if fails if(!$response) { die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl)); } var_dump($response); } // close curl resource to free up system resources curl_close($curl);
额外说明
- 添加
"Expect:"空头部可禁用Expect:100-continue机制,避免部分服务器对该响应处理异常导致的超时问题 - 确保
$jsondata是通过json_encode()生成的合法JSON字符串
内容的提问来源于stack exchange,提问作者der-htc
相关产品推荐
相关产品推荐

