我发现了一个脚本,可以从curl_multi请求中获得异步响应:
function rolling_curl($urls, $callback, $custom_options = null) {
// make sure the rolling window isn't greater than the # of urls
$rolling_window = 100;
$rolling_window = (sizeof($urls) < $rolling_window) ? sizeof($urls) : $rolling_window;
$master = curl_multi_init();
$curl_arr = array();
// add additional curl options here
$std_options = array(CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5);
$options = ($custom_options) ? ($std_options + $custom_options) : $std_options;
$hosts = array();
// start the first batch of requests
for ($i = 0; $i < $rolling_window; $i++) {
$hosts[$i]=parse_url($urls[$i], PHP_URL_HOST);
$ch = curl_init();
$options[CURLOPT_URL] = $urls[$i];
curl_setopt_array($ch,$options);
curl_multi_add_handle($master, $ch);
}
do {
while(($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
if($execrun != CURLM_OK)
break;
// a request was just completed -- find out which one
while($done = curl_multi_info_read($master)) {
$info = curl_getinfo($done['handle']);
if ($info['http_code'] == 200) {
$output = curl_multi_getcontent($done['handle']);
// request successful. process output using the callback function.
$id = array_search(parse_url($info['url'], PHP_URL_HOST),$hosts);
$callback($output,true, $id);
// start a new request (it's important to do this before removing the old one)
if(@$u = $urls[$i++]){
$ch = curl_init();
$options[CURLOPT_URL] = $u; // increment i
curl_setopt_array($ch,$options);
curl_multi_add_handle($master, $ch);
}
// remove the curl handle that just completed
curl_multi_remove_handle($master, $done['handle']);
} else {
$callback("",false);
}
}
} while ($running);
curl_multi_close($master);
return true;
}
这已经由我编辑了,因为我试图做的是在回调函数上保持url数组输入的索引。例如,如果输入数组是
$urls = array(0=> $url0, 1=> $url1, ...);
然后我希望当url1上的curl请求完成时,使用$ id = 1触发$ callback,以便我知道如何管理返回的数据,因为我知道它是url1。为了做到这一点,我想到在urls数组中找到curl url,但有时curl遵循redirect,所以它并不总是有效。然后我想到比较主机(幸运的是每个url在我的情况下都有不同的主机)并且它可以工作:我在创建curl句柄时创建一个主机数组,当请求完成时,我找到卷曲主机的索引到数组中。 这不是获得我想要的最好的方法,因为网址与主机相同,它不会起作用,也许有一种棘手且更简单的方法。 获取url索引的最佳方法是哪种? PS:我的回调函数是
function callback($output,$success,$id){...}