【问题标题】:Reading curl request progress headers with Guzzle使用 Guzzle 读取 curl 请求进度标头
【发布时间】:2019-03-26 09:07:11
【问题描述】:

使用 php 调用 curl 时,我可以在 CURLOPT_PROGRESSFUNCTION 上挂钩回调,并在请求过程中使用 curl_multi_getcontent($handle) 读取标头

$handle = curl_init()
curl_setopt(CURLOPT_NOPROGRESS, false)
curl_setopt(CURLOPT_RETURNTRANSFER, true)
curl_setopt(CURLOPT_PROGRESSFUNCTION, function($handle) {
   $response = curl_multi_getcontent($handle);
   // some logic here
})
curl_exec($handle)

如何使用 Guzzle 做到这一点?

问题是如果不将CURLOPT_RETURNTRANSFER 设置为true,我将无法使用curl_multi_getcontent($handle)

但是当我将CURLOPT_RETURNTRANSFER 设置为guzzle' curl 配置时,我可以读取正在进行的标题功能$response = curl_multi_getcontent($handle); 但是响应流包含空内容。

$request->getResponse()->getBody()->getContents(); // always outputs ""

编辑: 我已经做了这个更改https://github.com/guzzle/guzzle/pull/2173,所以我可以使用进度设置访问处理中的回调:

'progress' => function($handle) {
   $response = curl_multi_getcontent($handle);
   // some logic here
})

只要CURLOPT_RETURNTRANSFERtrue,它就可以工作。但是正如我之前提到的,响应内容是""

【问题讨论】:

    标签: php curl guzzle


    【解决方案1】:

    有一个进度请求选项。

    // Send a GET request to /get?foo=bar
    $result = $client->request(
        'GET',
        '/',
        [
            'progress' => function(
                $downloadTotal,
                $downloadedBytes,
                $uploadTotal,
                $uploadedBytes
            ) {
                //do something
            },
        ]
    );
    

    http://docs.guzzlephp.org/en/stable/request-options.html#progress

    【讨论】:

    • 是的,但这并不能解决如何在那里读取标题并读取响应。我已经设法通过我对 Guzzle github.com/guzzle/guzzle/pull/2173 实施的更改获得了 Handle,因此我可以在请求过程中读取标头,如本行 $response = curl_multi_getcontent($handle); 所述。但随后$request->getResponse()->getBody()->getContents() 为空("")。
    • 您可以选择在 Guzzle 中使用 PSR-7 流吗?将 getBody() 响应转换为字符串时会发生什么?
    • 它是空的。我已经找到了答案。即将发布。不过谢谢!
    【解决方案2】:

    我找到了解决方案,或者更确切地说找到了它发生的原因。

    默认情况下,当未定义自定义接收器时,Guzzle 设置 CURLOPT_FILE 选项(或在定义接收器时设置 CURLOPT_WRITEFUNCTION,但这实际上并不重要)。

    但是,将 CURLOPT_RETURNTRANSFER 设置为 true 会否定这两个选项 -> 它们不再适用。

    设置CURLOPT_RETURNTRANSFER后会发生两件事:

    1. 可以在PROGRESSFUNCTION$response = curl_multi_getcontent($handle) 中读取响应。为此,需要进行 Guzzle 修改https://github.com/guzzle/guzzle/pull/2173
    2. 当 Guzzle 调用 curl_exec($handle) 作为此调用的返回值时返回响应。但是 Guzzle 没有将它分配给任何变量,因为它希望响应不会在那里返回,而是通过 WRITEFUNCTION 返回,但是通过设置 CURLOPT_RETURNTRANSFER 被中和。

    所以我的解决方案不是最干净的,但我没有找到任何其他方法来解决它与 Guzzle。 Guzzle 根本无法处理这个问题。

    我分叉了 Guzzle。然后创建自定义 Stream 类,其行为类似于默认接收器 -> 写入php://temp。当我的自定义 Stream 类设置为接收器时,我将 curl_exec 的结果写入流:

    $result = curl_exec($easy->handle);
    $easy->sink->write($result);
    

    【讨论】:

      猜你喜欢
      • 2019-12-17
      • 2017-10-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多