osx平台调用curl_multi_exec失败脚本死循环

来源:互联网 发布:好玩的手机rpg 知乎 编辑:程序博客网 时间:2024/05/20 11:24


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

0 0
原创粉丝点击