note 88454 deleted from function.curl-multi-exec by danbrown

From: Date: Sun, 25 Jan 2009 16:55:39 +0000
Subject: note 88454 deleted from function.curl-multi-exec by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-149756@lists.php.net to get a copy of this message
Note Submitter: jorge dot hebrard at gmail dot com ---- Based on the below comments, I made a simple class. See note below code. <?php /** * Multiple Curl Handlers * @author Jorge Hebrard ( jorge.hebrard@gmail.com ) **/ class curlNode{ static private $listenerList; private $callback; public function __construct($url){ $new =& self::$listenerList[]; $new['url'] = $url; $this->callback =& $new; } /** * Callbacks needs 3 parameters: $url, $html (data of the url), and $lag (execution time) **/ public function addListener($callback){ $this->callback['callback'] = $callback; } /** * curl_setopt() wrapper. Enjoy! **/ public function setOpt($key,$value){ $this->callback['opt'][$key] = $value; } /** * Request all the created curlNode objects, and invoke associated callbacks. **/ static public function request(){ //create the multiple cURL handle $mh = curl_multi_init(); $running=null; # Setup all curl handles # Loop through each created curlNode object. foreach(self::$listenerList as &$listener){ $url = $listener['url']; $current =& $ch[]; # Init curl and set default options. # This can be improved by creating $current = curl_init(); curl_setopt($current, CURLOPT_URL, $url); # Since we don't want to display multiple pages in a single php file, do we? curl_setopt($current, CURLOPT_HEADER, 0); curl_setopt($current, CURLOPT_RETURNTRANSFER, 1); # Set defined options, set through curlNode->setOpt(); if (isset($listener['opt'])){ foreach($listener['opt'] as $key => $value){ curl_setopt($current, $key, $value); } } curl_multi_add_handle($mh,$current); $listener['handle'] = $current; $listener['start'] = microtime(1); } unset($listener); # Main loop execution do { # Exec until there's no more data in this iteration. # This function has a bug, it while(($execrun = curl_multi_exec($mh, $running)) == CURLM_CALL_MULTI_PERFORM); if($execrun != CURLM_OK) break; # This should never happen. Optional line. # Get information about the handle that just finished the work. while($done = curl_multi_info_read($mh)) { # Call the associated listener foreach(self::$listenerList as $listener){ # Strict compare handles. if ($listener['handle'] === $done['handle']) { # Get content $html = curl_multi_getcontent($done['handle']); # Call the callback. call_user_func($listener['callback'], $listener['url'], $html,(microtime(1)-$listener['start'])); # Remove unnecesary handle (optional, script works without it). curl_multi_remove_handle($mh, $done['handle']); } } } # Required, or else we would end up with a endless loop. # Without it, even when the connections are over, this script keeps running. if (!$running) break; # I don't know what these lines do, but they are required for the script to work. while (($res = curl_multi_select($mh)) === 0); if ($res === false) break; # Select error, should never happen. } while (true); # Finish out our script ;) curl_multi_close($mh); } } $curlGoogle = new curlNode('http://www.google.com/'); $curlGoogle->setOpt(CURLOPT_HEADER, 0); $curlGoogle->addListener('callbackGoogle'); $curlMySpace = new curlNode('http://www.myspace.com/'); $curlMySpace->addListener('callbackMySpace'); curlNode::request(); ?> NOTE: I think curl has a bug managing local files, when multiple handles are set. I tested with a local file, giving me 0.1~ sec. latency. Then I added another handle, google. With this new addition, my original file had a latency of 1.0~ sec. latency!! But with external sites (try Yahoo and Google), the latency is not a problem. Google alone gives me 1.7~ sec. latency, and with Yahoo, Google gives me 1.8~ sec. latency. If anyone can explain, I will be very granted.

« previous php.notes (#149756) next »