From a1f7bc6ad4f161448adc69c319ea179f778acc61 Mon Sep 17 00:00:00 2001 From: Shayetet Date: Fri, 14 Aug 2026 11:51:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E4=B8=AA=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=B9=B6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- src/common.php | 11 ++++++ src/extend/HttpExtend.php | 76 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/common.php b/src/common.php index 868b3dc9..10d6109e 100644 --- a/src/common.php +++ b/src/common.php @@ -389,6 +389,17 @@ function http_post(string $url, $data, array $options = []) return HttpExtend::post($url, $data, $options); } } +if (!function_exists('http_multi')) { + /** + * 并发执行多个HTTP请求. + * @param array $requests 请求配置 [['method' => 'GET', 'url' => '...', 'options' => [...]]] + * @return array + */ + function http_multi(array $requests): array + { + return HttpExtend::multiRequest($requests); + } +} if (!function_exists('data_save')) { /** * 数据增量保存. diff --git a/src/extend/HttpExtend.php b/src/extend/HttpExtend.php index 912a7dc7..cb907f7e 100644 --- a/src/extend/HttpExtend.php +++ b/src/extend/HttpExtend.php @@ -104,6 +104,79 @@ public static function request(string $method, string $location, array $options } } $curl = curl_init(); + static::configureCurl($curl, $method, $location, $options); + $content = curl_exec($curl); + curl_close($curl); + return $content; + } + + /** + * 并发执行多个HTTP请求. + * @param array $requests 请求配置 [['method' => 'GET', 'url' => '...', 'options' => [...]]] + * @return array + */ + public static function multiRequest(array $requests): array + { + if (empty($requests)) { + return []; + } + + $multiHandle = curl_multi_init(); + $curlHandles = []; + $results = []; + + // 初始化所有curl句柄 + foreach ($requests as $index => $request) { + $method = $request['method'] ?? 'GET'; + $location = $request['url'] ?? ''; + $options = $request['options'] ?? []; + + // GET 参数设置 + if (!empty($options['query'])) { + $location .= strpos($location, '?') !== false ? '&' : '?'; + if (is_array($options['query'])) { + $location .= http_build_query($options['query']); + } elseif (is_string($options['query'])) { + $location .= $options['query']; + } + } + + $curl = curl_init(); + static::configureCurl($curl, $method, $location, $options); + curl_multi_add_handle($multiHandle, $curl); + $curlHandles[$index] = $curl; + $results[$index] = false; + } + + // 执行所有请求 + $running = null; + do { + curl_multi_exec($multiHandle, $running); + curl_multi_select($multiHandle); + } while ($running > 0); + + // 获取所有请求的结果 + foreach ($curlHandles as $index => $curl) { + $results[$index] = curl_multi_getcontent($curl); + curl_multi_remove_handle($multiHandle, $curl); + curl_close($curl); + } + + curl_multi_close($multiHandle); + + // 保持原始顺序返回结果 + return array_values($results); + } + + /** + * 配置CURL句柄. + * @param mixed $curl CURL句柄 + * @param string $method 请求方式 + * @param string $location 请求地址 + * @param array $options 请求参数 + */ + private static function configureCurl($curl, string $method, string $location, array $options): void + { // Agent 代理设置 curl_setopt($curl, CURLOPT_USERAGENT, $options['agent'] ?? static::getUserAgent()); // Cookie 信息设置 @@ -154,9 +227,6 @@ public static function request(string $method, string $location, array $options curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); - $content = curl_exec($curl); - curl_close($curl); - return $content; } /**