通常情况下 PHP 中的 cURL 是阻塞运行的,就是说创建一个 cURL 请求以后必须等它执行成功或者超时才会执行下一个请求,curl_multi_* 系列函数使并发访问成功可能,PHP 文档对这个函数的介绍不太详细,用法如下:
$requests = array('http://zz.dongsheng.org', 'http://www.google.com');
$main = curl_multi_init();
$results = array();
$errors = array();
$info = array();
$count = count($requests);
for($i = 0; $i < $count; $i++) {
$handles[$i] = curl_init($requests[$i]);
var_dump($requests[$i]);
curl_setopt($handles[$i], CURLOPT_URL, $requests[$i]);
curl_setopt($handles[$i], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($main, $handles[$i]);
}
$running = 0;
do {
curl_multi_exec($main, $running);
} while($running > 0);
for($i = 0; $i < $count; $i++)
{
$results[] = curl_multi_getcontent($handles[$i]);
$errors[] = curl_error($handles[$i]);
$info[] = curl_getinfo($handles[$i]);
curl_multi_remove_handle($main, $handles[$i]);
}
curl_multi_close($main);
var_dump($results);
var_dump($errors);
var_dump($info);
通过这种方式就可以实现多任务并发执行,更详细的用法看我写的这个类:curl class
如何获得每个handle的错误信息呢?curl_error()在非并行时是正常的,并行时就不好用了。
可以的,我把代码修改了一下以捕获错误信息
测试了一下,并不起作用,比如把第二个链接改成”www.google”,errorcode是0。
从php手册上找到了这个:,难道说这就是个bug?
Hi, Ven
我又测试了一下,第一地址 zz.dongsheng.org 返回了错误 Couldn’t resolve host zz.dongsheng.org
PHP 文档里的 comment 已经很老了是 07 年的,可能新版的 PHP 已经修复了这个错误,我现在用的是 5.2.8,你用的是什么版本呢?
汗~~~5.2.6,回头升级到最新版试试。
找到原因了,似乎跟使用者网络环境有关。
由于curl_error()对301、404等http错误不做反应,所以如果使用者的网络对错误的域名返回http错误码的话,curl_error()自然不会有值。
相当扯淡,因为我这里有电信劫持的问题,所有无法解析的域名都被劫持到114的一个页面上了,所以对于”http://www.google”、”zz.dongsheng.org”这一类本来是错误的域名,却被电信劫持弄成了“正常的”网页。而在我的虚拟主机上,主机自动对无法解析的域名返回301,所以同样不会有curl_error()。
似乎是这样,望CDS给予指正或补充。
找到原因了,不是curl的问题,和使用者的网络环境有关系。
首先curl_error()是不对http错误作反应的。有些地方的网络对于错误的域名返回一个301(我的博客空间就是这样),这样curl_error()就没有返回值。而我本地有电信劫持问题,错误的域名会被劫持到114的网站上,那么自然也不存在错误了。
望CDS给予指正。
非常感谢您的耐心解答。