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


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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值