Php http parsing extension: php_http_parser is a PHP extension based on node. js http-parser and can be used to implement pure asynchronous PHP programs.
Libcurl provides two asynchronous calling methods:
One multi handle implements easy handles: add multiple easy handle and execute the curl_multi_perform method. This method is implemented in php curl extension. But in the last step, curl_multi_perform is blocked.
MULTI_SOCKET: this is a real non-blocking method, but it is difficult to implement event loop by yourself and it is not implemented in php at present. After investigation, it is very difficult to combine curl_multi_socket_action with the php kernel.
In addition, php extensions for asynchronous http requests are basically not implemented. Currently, only some php-only versions are available, such as the http client implementation in tsf. The problem of pure php implementation is mainly limited by the performance of http parsing. Therefore, we need to extend this module. Node. js http-parser is a good http parsing library in C language. Php_http_parser is an encapsulation of php_http_parser, which exposes corresponding interfaces in php.
To implement real non-blocking requests, you still need to implement the event loop by yourself. We recommend that you use swoole for better performance.
Usage
$buffs = array("HTTP/1.1 301 Moved Permanently\r\n","Location: http://www.google.com/\r\n","Content-Type: text/html; charset=UTF-8\r\n","Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n","Expires: Tue, 26 May 2009 11:11:49 GMT\r\n","Cache-Control: public, max-age=2592000\r\n","Server: gws\r\n","Content-Length: 193\r\n","\r\n","
\n","301 Moved\n","301 Moved\n","The document has moved\n","here.\r\n" ,"here.\r\n" ,"here.\r\n" ,"here.\r\n" ,"here.\r\n","\r\n");$hp = new HttpParser();foreach($buffs as $buff){ $ret = $hp->execute($buff); if($ret !== false){ echo $ret; break; }}
Although http requests may be sent through subcontracting, HttpParser will combine all packages, initiate the body event, and then call the corresponding callback method. For example, header callback is not implemented yet. In addition, you need to implement the timeout logic on your own.
The sample code is an asynchronous http client combined with the swoole_client and swPromise framework. So that you can implement real non-blocking PHP programs.
class HttpClientFuture implements FutureIntf { protected $url = null; protected $post = null; protected $proxy = false; public function __construct($url, $post = array(), $proxy = array()) { $this->url = $url; $this->post = $post; if($proxy){ $this->proxy = $proxy; } } public function run(Promise &$promise) { $cli = new \swoole_client ( SWOOLE_TCP, SWOOLE_SOCK_ASYNC ); $urlInfo = parse_url ( $this->url ); if(!isset($urlInfo ['port']))$urlInfo ['port'] = 80; $httpParser = new \HttpParser(); $cli->on ( "connect", function ($cli)use($urlInfo){ $host = $urlInfo['host']; if($urlInfo['port'])$host .= ':'.$urlInfo['port']; $req = array(); $req[] = "GET {$this->url} HTTP/1.1\r\n"; $req[] = "User-Agent: PHP swAsync\r\n"; $req[] = "Host:{$host}\r\n"; $req[] = "Connection:close\r\n"; $req[] = "\r\n"; $req = implode('', $req); $cli->send ( $req ); } ); $cli->on ( "receive", function ($cli, $data = "") use(&$httpParser, &$promise) { $ret = $httpParser->execute($data); if($ret !== false){ $cli->close(); $promise->accept(['http_data'=>$ret]); } } ); $cli->on ( "error", function ($cli) use(&$promise) { $promise->reject (); } ); $cli->on ( "close", function ($cli) { } ); if($this->proxy){ $cli->connect ( $this->proxy['host'], $this->proxy ['port'], 1 ); }else{ $cli->connect ( $urlInfo ['host'], $urlInfo ['port'], 1 ); } }}
Project homepage:Http://www.open-open.com/lib/view/home/1448201436622