发现在windows和linux平台上运行良好的curl_multi_exec脚本在OSX却总是一直运行并且没有返回结果,找遍百度没有答案。
很郁闷这个问题纠缠了我一下午,我本地php版本:
andy@AndyMacBookPro:~$ php -v
PHP 5.4.24 (cli) (built: Jan 19 2014 21:32:15)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
andy@AndyMacBookPro:~$
使用脚本:
<?php
// 创建一对cURL资源
$ch1 = curl_init();
$ch2 = curl_init();
// 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 增加2个句柄
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
$active = null;
$i=0;
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
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_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>
此脚本只会一直执行而没有任何返回,相当于无效。
关于此问题的解决方法我参考了这里:
http://stackoverflow.com/questions/19999403/curl-multi-exec-fails-on-mac-os-x
还有这篇文章的一些参考:
https://bugs.php.net/bug.php?id=63411
http://marchtea.com/?p=109
他们的解释:
On php 5.3.18+ be aware that curl_multi_select() may return -1 forever until you call curl_multi_exec().
Try this:
while ($this->active && $mrc == CURLM_OK)
{
// add this line
while (curl_multi_exec($this->mh, $this->active) === CURLM_CALL_MULTI_PERFORM);
if (curl_multi_select($this->mh) != -1)
{
do {
$mrc = curl_multi_exec($this->mh, $this->active);
if ($mrc == CURLM_OK)
{
while($info = curl_multi_info_read($this->mh))
{
$this->process($info);
}
}
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
重写之后的方法是:
<?php
$ch1 = curl_init();
$ch2 = curl_init();
// 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net");
curl_setopt($ch2, CURLOPT_HEADER, 0);
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 增加2个句柄
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
$active = null;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK)
{
// add this line
while (curl_multi_exec($mh, $active) === CURLM_CALL_MULTI_PERFORM);
if (curl_multi_select($mh) != -1)
{
do {
$mrc = curl_multi_exec($mh, $active);
if ($mrc == CURLM_OK)
{
while($info = curl_multi_info_read($mh))
{
var_dump($info);
}
}
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>
解决方法是有了,但是希望有人能给出第一个脚本无法在OSX正常运行的原因。
另外来自于:http://blog.marchtea.com/archives/109#comment-13220
的看法是这样的:
关键在于在while循环中要执行curl_multi_exec
,直到处理完毕再进入select
.