Last active
August 29, 2015 13:58
-
-
Save ollietb/10104310 to your computer and use it in GitHub Desktop.
Multi curl example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Taken from https://bugs.php.net/bug.php?id=63842 | |
* / | |
$MAX_SIMULTANEOUS = 50; // Adjust to whatever number of maximum simultaneous requests you think is appropriate. | |
// Fill array $reqList[] with whatever data you're using to generate your CURL requests, | |
// one request per array element, with consecutive indices starting at 0. | |
// note that requests at the END of the array will be started first. | |
if ($i = count($reqList)) // check that there is something to do... | |
{ | |
$handleMap = array(); // use this to associate curl handles with the data that created them | |
$curlMH = curl_multi_init(); | |
$x = $i - $MAX_SIMULTANEOUS; if ($x<0) $x = 0; | |
while ($i>$x) initRequest($reqList[--$i]); | |
do | |
{ | |
while (($mrc = curl_multi_exec($curlMH, $active)) === CURLM_CALL_MULTI_PERFORM); | |
if ($mrc !== CURLM_OK) break; // Shouldn't normally ever happen; look at the list of CURLM_ errors to see when it might. | |
while ($info = curl_multi_info_read($curlMH)) // a request has completed | |
{ | |
$ch = $info['handle']; | |
$k = intval(substr((string) $ch, 13)); | |
if (($errno = $info['result']) === CURLE_OK) processResult($handleMap[$k][1], curl_multi_getcontent($ch)); | |
else ... // handle failed CURL request, (e.g. write to the error log or database, output a message, etc.) | |
if ($i) initRequest($reqList[--$i]); // start new request if one is waiting | |
curl_multi_remove_handle($curlMH, $ch); curl_close($ch); unset($handleMap[$k]); // clean up completed request | |
} | |
// wait for next CURL operation to complete, or sleep a short time if CURL is busy but unable to "block" using curl_multi_select | |
if ($active && (curl_multi_select($curlMH) === -1)) usleep(50); | |
} | |
while ($active); | |
if ($mrc !== CURLM_OK) ... // optinally handle CURLM_ errors (e.g. write to error log, output message, etc.) | |
// clean up | |
foreach ($handleMap as $ch) { curl_multi_remove_handle($curlMH, $ch[0]); curl_close($ch); } | |
curl_multi_close($curlMH); | |
$reqList = $curlMH = $handleMap = null; | |
} | |
function initRequest($reqData) | |
{ | |
global $curlMH, $handleMap; | |
// process $reqData to get $url (the request URL), and any POST data, or other CURL options. | |
// also generate $custReqData, which will be passed to processResult to identify the request | |
// when it has completed (may be the same as $reqData). | |
$ch = curl_init($url); | |
curl_setopt($ch, ...); // set other CURL options | |
curl_setopt($ch, ...); | |
curl_multi_add_handle($curlMH, $ch); | |
$handleMap[intval(substr((string) $ch, 13))] = array($ch, $custReqData); | |
} | |
function processResult($custReqData, $response) | |
{ | |
// process $response (the data returned from the CURL request) | |
// using $custReqData to identify which request it belongs to. | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment