PHP手册中对curl_multi的描述太不全了,各种版本的实现也有,之前一直就想写这个东西,终于在今天下午写了一个类封装了一下, 应该能满足大多数的应用场景。
代码 https://github.com/walu/yun-lib/blob/master/f1/Yun/Curl/Multi.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//详细api请参阅代码相应方法注释
$ycm
=
new
Yun_Curl_Multi();
$option
=
array
(CURLOPT_RETURNTRANSFER=>true);
$url_conn
[
$url
] =
$ycm
->addUrl(
$url
,
$option
);
$url_conn
[
$url
] =
$ycm
->addUrl(
$url
,
$option
);
$url_conn
[
$url
] =
$ycm
->addUrl(
$url
,
$option
);
//每一次请求结束后都会立即调用callback
//适合bigpipe类应用
$ycm
->doAndCallback(
$callback_function
);
//或者这么用
//所有请求结束后返回结果
$content
=
$ycm
->doAndGetResult();
//所有请求结束后返回结果
|
curl multi 的用法
- 先建立multi handler
- 第一次调用exec,生成与服务器的链接
- 循环调用exec,非阻塞形式的执行请求。期间注意select,否则cpu会被循环搞到发飙的。
需要注意的地方
### curl_multi_exec的调用方法
这里是造成大家迷惑的主要地方,为什么有的demo用了CURLM_CALL_MULTI_PERFORM返回值检查,有的demo却没有。这个 地方很简单,查阅一下curl的手册便可以了。
curl_multi_exec在底层调用了libcurl的curl_multi_perform函数。在curl7.20.0以前,此函数会返回一个CURLM_CALL_MULTI_PERFORM值,代表它希望立刻再一次被调用(文档)。所以就有了检查此返回值,再一次调用curl_multi_exec函数的demo。在7.20.0(含)之后,libcurl把这个工作自己在内部做了,所以就不用应用端再做了,直接调用curl_multi_exec,只检查$still_running参数就行了。
左边的是curl7.19.7,右边的是7.20.0,一看便知
这里就有人可能会全都按照7.19.7的来写,我觉得不是很妥。因为毕竟curl在逻辑上把这个返回值给弃用了,说不定哪天php中的curl扩展 也会去掉这个常量的,从而因为使用过期的api而导致系统故障。
select 问题
没有select的话,cpu会因为循环而飙的很高,这当然不是我们希望看到的。所以必须用curl_multi_select函数来阻塞。
如果是bigpipe应用,一定要用callback
检查一下你的代码,是否为等待所有请求结束后才执行业务逻辑的?如果是,则快改正吧。
完