Search code examples
phpmacoscurlcurl-multi

curl_multi_exec fails on Mac OS X


I'm trying to run this simple piece of code from php.net under my Mac OS X (Mavericks) to try cURL multi exec feature :

<?php
    // create both cURL resources
    $ch1 = curl_init();
    $ch2 = curl_init();

    // set URL and other appropriate options
    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);

    //create the multiple cURL handle
    $mh = curl_multi_init();

    //add the two handles
    curl_multi_add_handle($mh,$ch1);
    curl_multi_add_handle($mh,$ch2);

    $active = null;
    //execute the handles
    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);
        }
    }

    //close the handles
    curl_multi_remove_handle($mh, $ch1);
    curl_multi_remove_handle($mh, $ch2);
    curl_multi_close($mh);

    ?>

That does not work as the only output I got is :

PHP Fatal error: Maximum execution time of 30 seconds exceeded in

This is my environment: Mac OS X 10.9, PHP 5.4.17, Apache 2.2.24.

cUrl is installed as I my regular curl "single" requests work great.

I think this is an issue with Mac OS but I can't find any fix. Do you have any idea?

EDIT: I tried the same code on a Linux server and everything worked fine.


Solution

  • 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);
       }   
    } 
    

    See https://bugs.php.net/bug.php?id=63411 or http://marchtea.com/?p=109 for more information.