2018年6月

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();
}

- 阅读剩余部分 -