You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP使用生成器封装GuzzleHttp\Pool响应时返回null报错如何解决

问题根因

\GuzzleHttp\Pool的promise()->wait()默认返回值为null,不会自动聚合所有请求的响应结果,因此你尝试遍历null就触发了foreach参数类型错误。
另外你最初版本的代码没有实现真正的并发:每次发起异步请求后立刻调用wait(),会阻塞等待当前请求返回后才发起下一个请求,本质还是同步串行请求。

修正方案

需要在Pool的配置参数中添加fulfilled回调主动收集成功的响应结果,同时可添加rejected回调处理请求异常场景,等所有请求执行完成后遍历自己收集的结果数组即可。

修正后的可运行代码如下:

function prepare_requests(int $total): \Generator
{
    for ($i = 0; $i < $total; $i++) {
        $uri = "https://httpbin.org/anything?q=$i";
        yield new \GuzzleHttp\Psr7\Request('GET', $uri);
    }
}

function do_pool_requests(\GuzzleHttp\Client $client, int $total): \Generator
{
    // 自定义数组存储请求结果
    $results = [];
    $pool = new \GuzzleHttp\Pool($client, prepare_requests($total), [
        'concurrency' => 25,
        // 成功回调,收集响应
        'fulfilled' => function (\GuzzleHttp\Psr7\Response $response, $index) use (&$results) {
            $results[$index] = [
                'headers' => $response->getHeaders(),
                'response' => $response->getBody()->getContents()
            ];
        },
        // 失败回调,可自定义错误处理
        'rejected' => function (\GuzzleHttp\Exception\RequestException $e, $index) use (&$results) {
            $results[$index] = [
                'error' => $e->getMessage()
            ];
        }
    ]);

    // wait()执行完成后,所有结果已经存入$results数组
    $pool->promise()->wait();
    
    // 按请求顺序返回结果
    ksort($results);
    foreach ($results as $item) {
        yield $item;
    }
}

$client = new \GuzzleHttp\Client();

foreach (do_pool_requests($client, 100) as $do_request) {
    var_dump($do_request);
}
补充说明
  • 回调中的$index参数对应请求生成的顺序,处理完成后用ksort排序可以保证返回结果和你发起请求的顺序一致
  • 并发参数concurrency的配置已经生效,会严格控制最多同时发起25个请求

内容的提问来源于stack exchange,提问作者VBobCat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 19:27:06