PHP标准库内置curl扩展,不过实现不完整,如multi_socket_action接口,无意中发现pecl http库同样基于libcurl封装,支持更多的libcurl特性,更新也比较快,底层通过libevent(epoll)实现multi_socket_action接口,不过pecl http版本1和版本2 api完全不兼容,使用过程中稳定性及性能并不如PHP内置的curl,好像还有内存泄露,以下为示例代码,基于pecl_http 2.20:
<?php
function push($client, $url) {
$req = new http\Client\Request("GET", $url, ["User-Agent"=>"My Client/0.1"]);
$req->setOptions(array('connecttimeout'=>1, 'timeout'=>1));
$client->enqueue($req, function($response) use ($client, $req, $url) {
printf("%s returned '%s' (%d)\n", $response->getTransferInfo("effective_url"), $response->getInfo(), $response->getResponseCode());
echo $client->count().PHP_EOL;
global $urls;
if ($urls) {
while ($client->count() < 20) {
$url = array_shift($urls);
push($client, $url);
}
return true; // dequeue
}
});
}
$client = new http\Client;
$client->enablePipelining(true);
$client->enableEvents(true);
for ($i = 0; $i < 10000; ++$i) {
$urls[] = "http://192.168.1.3/";
}
for ($i = 0; $i < 20; ++$i) {
$url = array_shift($urls);
push($client, $url);
}
/*
try{
var_dump($client->send());
}
catch(http\Exception\RuntimeException $e)
{
echo 'Message: ' .$e->getMessage().PHP_EOL;
}
*/
while ($client->once()) {
$client->wait();
}