如何将单cURL请求方法改造为支持多cURL的通用方法
改造PHP单cURL方法为支持多cURL的通用方法
改造思路
核心是统一用curl_multi机制处理请求,同时兼容单请求调用场景——先将输入格式统一为数组,批量初始化curl句柄,执行多请求循环后,再根据原始输入格式返回对应结果(单个响应/响应数组),既保留原有单请求的调用习惯,又实现多请求的高效处理。
改造后的通用方法代码
private function curlRequest(mixed $requests): mixed { // 统一输入格式:单个请求转数组,方便批量处理 $isSingleRequest = false; if (!is_array($requests) || (isset($requests['url']) && !is_array($requests['url']))) { $isSingleRequest = true; $requests = [$requests]; } $multiHandle = curl_multi_init(); $handles = []; $results = []; // 全局默认配置 $defaultOptions = [ CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_TIMEOUT => 30 ]; // 初始化所有curl句柄并加入multi句柄 foreach ($requests as $key => $request) { // 支持两种请求格式:直接传URL字符串,或包含url和自定义options的数组 $url = is_string($request) ? $request : $request['url']; $customOptions = is_array($request) && isset($request['options']) ? $request['options'] : []; $ch = curl_init($url); curl_setopt_array($ch, array_merge($defaultOptions, $customOptions)); curl_multi_add_handle($multiHandle, $ch); $handles[$key] = $ch; } // 执行多cURL请求循环 do { $status = curl_multi_exec($multiHandle, $active); curl_multi_select($multiHandle); } while ($status === CURLM_CALL_MULTI_PERFORM || $active > 0); // 收集每个请求的响应与错误 foreach ($handles as $key => $ch) { $response = curl_multi_getcontent($ch); $error = curl_error($ch); if ($error) { $results[$key] = new Exception("请求{$key}出错: {$error}"); } else { $results[$key] = $response; } curl_multi_remove_handle($multiHandle, $ch); curl_close($ch); } curl_multi_close($multiHandle); // 还原返回格式:单请求返回单个结果,多请求返回结果数组 return $isSingleRequest ? $results[0] : $results; }
使用示例
1. 单个请求调用(兼容原有单cURL逻辑)
// 直接传URL字符串 $singleResponse = $this->curlRequest('https://api.example.com/user/1'); // 带自定义请求头的单请求 $singleResponse = $this->curlRequest([ 'url' => 'https://api.example.com/user/1', 'options' => [CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_TOKEN']] ]);
2. 多个请求批量调用
$batchRequests = [ 'user_info' => 'https://api.example.com/user/1', 'user_posts' => [ 'url' => 'https://api.example.com/user/1/posts', 'options' => [CURLOPT_TIMEOUT => 15] ] ]; $batchResponses = $this->curlRequest($batchRequests); // 结果可通过键名获取:$batchResponses['user_info']、$batchResponses['user_posts']
关键细节说明
- 格式兼容:支持多种输入格式,无需修改原有单请求的调用代码
- 错误隔离:单个请求出错不会中断整个批量任务,错误会被封装为Exception对象返回
- 资源清理:所有curl句柄和multi句柄都会被正确关闭,避免内存泄漏
- 性能优化:用
curl_multi_select()等待请求状态变化,减少CPU空转
内容的提问来源于stack exchange,提问作者Наталья Юрова
相关产品推荐
相关产品推荐

