PHP:http GET / POST以真正的异步方式

时间:2013-08-20 07:05:05

标签: php http curl asynchronous curl-multi

基本上,我正在寻找一种在PHP中执行以下操作的方法:

http_get_or_post('an.url', 'or.two');

// Do some work here, not worrying about the http going on in the background.

$r = wait_for_and_get_the_results_of_the_http_requests()

也许有更多卷曲经验的人可以确认curl_multi是我正在寻找的。

根据我从http://php.net/manual/en/function.curl-multi-init.php收集的内容,那里的样本可能会给我我需要的东西:

$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch1);

$active = null;
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

// Now, am I free to do some time consuming work here and not worry about
// calling curl_multi_exec every now and then to facilitate the background
// http / socket processes?

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

curl_multi_remove_handle($mh, $ch1);
curl_multi_close($mh);

现在,主要的问题是,我对这种做法的理解是正确的吗?

1)第一个循环只负责向套接字发送/写入请求。

2)发送请求后,所有的http / socket内容都会在后台发生,让我可以自由地做其他事情,而不必定期调用curl_multi_exec来确保某些缓冲区在某处不满并需要踢继续前进。

3)第二个循环将等待任何未完成的响应数据到达并完成读取和处理响应。

现在,这仍然不是完全异步的 - 如果套接字写入缓冲区填满,我可能会在写入请求时被阻止,但在我的场景中这不是问题,我只是担心必须调用curl_multi_exec而我我正在中间做其他事情,所以整个事情都不会冻结,直到下一次我打电话给curl_multi_exec。

对于2k-4k响应的一般场景,我也很好,在我进入第二个循环之前,更大的响应会在后台无所事事。

这是curl_multi的工作原理吗?如果没有,你能建议用PHP完成这项工作吗?

2 个答案:

答案 0 :(得分:0)

curl_multi一次只做一件非常小的工作。对curl_multi_exec的每次调用都会对传输操作进行一些分段,一旦你调用了足够多次数据并且已经发送和接收了数据,就完成了。

答案 1 :(得分:0)

刚做了一些测试,简而言之 - 不,这不是curl_multi的工作原理 - 你需要继续调用curl_multi_exec,没有这个,第一个循环只会设法在连接上进行TCP握手,而不是甚至发出请求。

很遗憾,使用mysqlnd的mysqli可以做异步请求,为什么不能卷曲?