Created
November 20, 2016 15:45
-
-
Save SuoXC/3502a30b577e136e26e5de4444c08f51 to your computer and use it in GitHub Desktop.
use php curl_multi_* to perform http requests
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 | |
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