用Guzzle读取curl请求进度标头 [英] Reading curl request progress headers with Guzzle
问题描述
使用php调用curl时,我可以在 CURLOPT_PROGRESSFUNCTION
上挂接回调,并在请求过程中使用 curl_multi_getcontent($ handle)
When calling curl with php, I'm able to hook callback on CURLOPT_PROGRESSFUNCTION
and read headers during the request progress using 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做到这一点?
How can I do that with Guzzle?
问题在于,如果不将 CURLOPT_RETURNTRANSFER
设置为 true
,就无法使用 curl_multi_getcontent($ handle)
.
The problem is that I cannot use curl_multi_getcontent($handle)
without setting CURLOPT_RETURNTRANSFER
to true
.
但是当我将 CURLOPT_RETURNTRANSFER
设置为狂饮"的curl配置时,我可以读取进度函数中的标头 $ response = curl_multi_getcontent($ handle);
但是响应流包含空内容.
But when I set CURLOPT_RETURNTRANSFER
to guzzle' curl config, I can read headers in progress function $response = curl_multi_getcontent($handle);
However the response stream contains empty content.
$request->getResponse()->getBody()->getContents(); // always outputs ""
我已经进行了此更改 https://github.com/guzzle/guzzle/pull/2173这样我就可以使用进度设置访问进行中的回叫处理
I have made this change https://github.com/guzzle/guzzle/pull/2173 so I can access handle in progress callback with progress settings:
'progress' => function($handle) {
$response = curl_multi_getcontent($handle);
// some logic here
})
只要 CURLOPT_RETURNTRANSFER
为 true
,此方法就有效.但是,正如我前面提到的,响应内容然后是"
.
That works as long as CURLOPT_RETURNTRANSFER
is true
. However as I mentioned earlier, the response contents is ""
then.
推荐答案
我找到了解决方案,或者只是解释了为什么发生这种情况.
I found the solution or rather an explanation why it is happening.
在未定义自定义接收器的情况下,
默认情况下会设置 CURLOPT_FILE
选项(或在定义接收器时设置 CURLOPT_WRITEFUNCTION
,但实际上并不重要).
Guzzle by default sets CURLOPT_FILE
option when no custom sink is defined (or CURLOPT_WRITEFUNCTION
when sink is defined but that doesn't really matter actually).
但是,将 CURLOPT_RETURNTRANSFER
设置为 true
会使这两个选项无效->它们不再适用.
However, setting CURLOPT_RETURNTRANSFER
to true
negates both of those options -> they're not applied anymore.
在设置 CURLOPT_RETURNTRANSFER
之后,发生了两件事:
Two things happen then after setting CURLOPT_RETURNTRANSFER
:
- 可以使用
- 响应.为此,必须进行> https://github.com/guzzle/guzzle/pull/2173 当Guzzle调用
- 响应.但是Guzzle不会将其分配给任何变量,因为它希望响应不会通过那里返回,而是通过
WRITEFUNCTION
返回,但是通过设置CURLOPT_RETURNTRANSFER
中立了.
$ response = curl_multi_getcontent($ handle)
在 PROGRESSFUNCTION
中读取 curl_exec($ handle)
作为此调用的返回值时,返回- Response can be read in
PROGRESSFUNCTION
with$response = curl_multi_getcontent($handle)
. For that this Guzzle modification is necessary https://github.com/guzzle/guzzle/pull/2173 - Response is returned when Guzzle calls
curl_exec($handle)
as return value of this call. But Guzzle doesn't assign it to any variable because it expects that the response is not returned there but throughWRITEFUNCTION
that was however neutralized by settingCURLOPT_RETURNTRANSFER
.
所以我的解决方案不是最干净的,但是我找不到其他方法来解决Guzzle的问题.食尸鬼根本就没有能力去解决这个问题.
So my solution is not the cleanest one but I don't find any other way to go around it with Guzzle. Guzzle is simply not built to be able to handle that.
我叉了嘴.然后创建行为类似于默认接收器->的自定义Stream类,该类写入 php://temp
.当我的自定义Stream类设置为接收器时,我将 curl_exec
的结果写入流中:
I forked Guzzle. Then created custom Stream class that behaves like default sink -> that writes to php://temp
. And when my custom Stream class is set as sink I write the result of curl_exec
into stream:
$result = curl_exec($easy->handle);
$easy->sink->write($result);
这篇关于用Guzzle读取curl请求进度标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!