Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
use php curl_multi_* to perform http requests
<?php
interface HandleIterator {
public function getNextHandle();
public function dataCallback($data);
}
class IndexHandleIterator implements HandleIterator{
private $curl;
private $count;
public function __construct(){
$this->curl = curl_init("http://localhost/index.php");
$this->count = 0;
curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,true);
}
public function getNextHandle(){
if($this->count > 1000){
return null;
}
$this->count ++;
$handle = curl_copy_handle($this->curl);
return $handle;
}
public function dataCallback($data){
echo $data;
}
}
function request_parallelly(HandleIterator $handleIterator,$window_size=10){
$multi = curl_multi_init();
for($i = 0; $i < $window_size;$i ++){
curl_multi_add_handle($multi,$handleIterator->getNextHandle());
}
//$time = microtime(true);
do{
while(($execrun = curl_multi_exec($multi, $running)) == CURLM_CALL_MULTI_PERFORM){ }
if($execrun != CURLM_OK){
break;
}
while($info = curl_multi_info_read($multi)) {
$handle = $info['handle'];
call_user_func([$handleIterator,'dataCallback'],curl_multi_getcontent($handle));
curl_multi_remove_handle($multi,$handle);
$nextHandle = $handleIterator->getNextHandle();
if(!empty($nextHandle)){
curl_multi_add_handle($multi,$nextHandle);
}
curl_close($handle);
}
//
if($running){ //如果这一批还没执行完
//阻塞,减少cpu占用
curl_multi_select($multi);
}
}while($running);
//echo microtime(true) -$time;
curl_multi_close($multi);
}
function request_one_by_one($iterator){
while(1){
$handle = $iterator->getNextHandle();
if(empty($handle)){
break;
}
call_user_func([$iterator,'dataCallback'],curl_exec($handle));
}
}
//test
$iterator = new IndexHandleIterator();
$start = microtime(true);
request_parallelly($iterator);
//request_one_by_one($iterator);
echo microtime(true) - $start;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment