自定义PHP CURL类复用连接时切换GET请求无返回问题排查
错误原因
- 仅设置
CURLOPT_CUSTOMREQUEST = 'GET'无法覆盖之前配置的CURLOPT_POST = true,CURL仍会按照POST逻辑处理请求 - 之前设置的
CURLOPT_POSTFIELDS参数未清空,残留的POST数据会导致请求逻辑异常 - 同一个CURL句柄会自动复用已设置的Cookie配置,不需要重复设置
CURLOPT_COOKIEFILE
修复方案
你当前的Par类本身已经使用同一个CURL句柄,只要两个请求的域名一致,默认就会复用TCP连接,只需要修正请求参数重置逻辑即可:
1. 调用逻辑修改(无需改类代码即可修复)
$url_auth = 'http://site=user_login'; $url = 'http://site_search&group=1'; $auth_data = array( "login" => "login", "password" => "pas", ); $parser = new Par(); $parser->set(CURLOPT_POST, true) ->set(CURLOPT_POSTFIELDS, http_build_query($auth_data)) ->set(CURLOPT_FOLLOWLOCATION, 1) ->set(CURLOPT_COOKIEJAR, __DIR__ .'/cook.txt') ->set(CURLOPT_COOKIEFILE, __DIR__ .'/cook.txt'); $data = $parser->exec($url_auth); print_r($data); // 重置POST相关配置 $parser->set(CURLOPT_POST, false) ->set(CURLOPT_POSTFIELDS, null) ->set(CURLOPT_CUSTOMREQUEST, null); $data = $parser->exec($url); print_r($data);
2. 类优化方案(更稳妥)
可以给Par类新增请求重置方法和错误检测逻辑,避免后续切换请求类型时再出现参数残留问题:
class Par { private $url; private $ch; public function __construct($print = false){ $this->ch = curl_init(); if (!$print){ curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); } // 显式开启TCP长连接,确保连接复用生效 curl_setopt($this->ch, CURLOPT_TCP_KEEPALIVE, 1); } public function set($name, $value){ curl_setopt($this->ch, $name, $value); return $this; } public function exec($url){ curl_setopt($this->ch, CURLOPT_URL, $url); $result = curl_exec($this->ch); // 新增错误输出,方便排查问题 if(curl_errno($this->ch)) { return 'CURL错误:' . curl_error($this->ch); } return $result; } // 切换请求类型前调用,清空旧请求的所有特殊配置 public function resetRequest() { curl_reset($this->ch); // 恢复基础全局配置 curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->ch, CURLOPT_TCP_KEEPALIVE, 1); return $this; } public function __destruct(){ curl_close($this->ch); } }
内容的提问来源于stack exchange,提问作者Oleg
相关产品推荐
相关产品推荐

