使用 curl_multi_init 执行并发请求

使用 curl_multi_init 执行并发请求

PHP 语言不像 JavaScript 那样具备异步回调的特性,实现并发也就有些棘手。不过对于服务器之间进行连接和通讯,PHP 良好支持了 libcurl 库,要执行一批并发请求,依靠 curl_multi_init 方法就可以轻松搞定。

通常,一个简单的 CURL 请求是这样被组装和发送的:

$ch = curl_init();

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_TIMEOUT, 10);

$data = curl_exec($ch);

curl_close($ch);

一旦 curl_exec 被执行,我们就可以捕获到 $data 变量,也就是所需要的响应结果。

换做 curl_multi_exec 同样有效,原生 PHP 允许并行地处理批处理 CURL 句柄。那么如何实现一批并发的 CURL 句柄呢?我们可以通过建立一个 CURL 批处理会话,来控制两个独立的 CURL 句柄。当会话需要执行时,通过 curl_multi_exec 去处理在栈中的一个句柄。封装成一个函数,基本是这样的:

function curl_multi ($query_arr) {

$ch = curl_multi_init();

$count = count($query_arr);

$ch_arr = array();

for ($i = 0; $i < $count; $i++) {

$query_string = $query_arr[$i];

$ch_arr[$i] = curl_init($query_string);

curl_setopt($ch_arr[$i], CURLOPT_RETURNTRANSFER, true);

curl_multi_add_handle($ch, $ch_arr[$i]);

}

$running = null;

do {

curl_multi_exec($ch, $running);

} while ($running > 0);

for ($i = 0; $i < $count; $i++) {

$results[$i] = curl_multi_getcontent($ch_arr[$i]);

curl_multi_remove_handle($ch, $ch_arr[$i]);

}

curl_multi_close($ch);

return $results;

}

最终所返回的数据是一个由单独 CURL 句柄响应组成的结果集数组。和单独请求相比,基本可以节约一半的时间。