发现在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
.