php_http_parser PHP的HTTP解析扩展开源项目

我要开发同款
匿名用户2015年11月18日
81阅读

技术信息

开源地址
https://github.com/coooold/php_http_parser
授权协议
MIT

作品详情

php_http_parser是基于ode.jshttp-parser的PHP扩展,可用于实现纯异步PHP程序

libcurl提供了异步调用方式,有两种风格:

ONEMULTIHANDLEMANYEASYHANDLES:加入多个easyhadle后执行curl_multi_perform方法。该方法在phpcurl扩展中有对应实现。但最后一步curl_multi_perform是阻塞的。

MULTI_SOCKET,这个是真正的非阻塞方法,但需要自行实现evetloop,且封装较为困难,目前在php中没有对应实现。经过调研,curl_multi_socket_actio跟php内核结合困难度很高。

除此之外,基本上没有真正的实现异步http请求的php扩展。目前仅有部分纯php实现的版本,比如tsf中的httpcliet实现。使用纯php实现的问题主要受限于http解析的性能。因此考虑将这一模块用扩展的方式来实现。ode.jshttp-parser就是一个很好的c语言的http解析库。php_http_parser就是对其做的一个封装,在php中暴露出相应的接口。

为了实现真正的非阻塞请求,仍然需要自己实现evetloop。目前推荐结合swoole使用,以获得更好的性能。

使用方式$buffs = array("HTTP/1.1 301 Moved Permaetly\r\","Locatio: https://www.google.com/\r\","Cotet-Type: text/html; charset=UTF-8\r\","Date: Su, 26 Apr 2009 11:11:49 GMT\r\","Expires: Tue, 26 May 2009 11:11:49 GMT\r\","Cache-Cotrol: public, max-age=2592000\r\","Server: gws\r\","Cotet-Legth: 193\r\","\r\","<HTML><HEAD><meta http-equiv=\"cotet-type\" cotet=\"text/html;charset=utf-8\">\","<TITLE>301 Moved</TITLE></HEAD><BODY>\","<H1>301 Moved</H1>\","The documet has moved\","<A HREF=\"https://www.google.com/\">here</A>.\r\"    ,"<A HREF=\"https://www.google.com/\">here</A>.\r\"    ,"<A HREF=\"https://www.google.com/\">here</A>.\r\"    ,"<A HREF=\"https://www.google.com/\">here</A>.\r\"    ,"<A HREF=\"https://www.google.com/\">here</A>.\r\","</BODY></HTML>\r\");$hp = ew HttpParser();foreach($buffs as $buff){    $ret = $hp->execute($buff);    if($ret !== false){        echo $ret;        break;    }}

虽然http请求可能分包发送,HttpParser会将所有包合并在一起后,出发body事件,然后调用相应的回调方法。诸如header回调,目前暂未实现。另外,此处需要自行实现timeout逻辑。

示例代码是结合swoole_cliet与swPromise框架实现的一个异步httpcliet。籍此可以实现真正的非阻塞的PHP程序。

class HttpClietFuture implemets FutureItf {    protected $url = ull;    protected $post = ull;    protected $proxy = false;    public fuctio __costruct($url, $post = array(), $proxy = array()) {        $this->url = $url;        $this->post = $post;        if($proxy){            $this->proxy = $proxy;        }    }    public fuctio ru(Promise &$promise) {        $cli = ew \swoole_cliet ( SWOOLE_TCP, SWOOLE_SOCK_ASYNC );        $urlIfo = parse_url ( $this->url );        if(!isset($urlIfo ['port']))$urlIfo ['port'] = 80;        $httpParser = ew \HttpParser();        $cli->o ( "coect", fuctio ($cli)use($urlIfo){            $host = $urlIfo['host'];            if($urlIfo['port'])$host .= ':'.$urlIfo['port'];            $req = array();            $req[] = "GET {$this->url} HTTP/1.1\r\";            $req[] = "User-Aget: PHP swAsyc\r\";            $req[] = "Host:{$host}\r\";            $req[] = "Coectio:close\r\";            $req[] = "\r\";            $req = implode('', $req);            $cli->sed ( $req );        } );        $cli->o ( "receive", fuctio ($cli, $data = "") use(&$httpParser, &$promise) {            $ret = $httpParser->execute($data);            if($ret !== false){                $cli->close();                $promise->accept(['http_data'=>$ret]);            }        } );        $cli->o ( "error", fuctio ($cli) use(&$promise) {            $promise->reject ();        } );        $cli->o ( "close", fuctio ($cli) {        } );        if($this->proxy){            $cli->coect ( $this->proxy['host'], $this->proxy ['port'], 1 );        }else{            $cli->coect ( $urlIfo ['host'], $urlIfo ['port'], 1 );        }    }}性能[web@gz-web01 php_http_parser]$ time /data/server/php/bi/php http_parser.php  2000000real    0m11.489suser    0m11.435ssys 0m0.017s

1个worker进程

./http_load -fetches 20000 -parallel 100 9502.listasyc 20000 fetches, 100 max parallel, 2.02e+06 bytes, i 5.94536 secods101 mea bytes/coectio3363.97 fetches/sec, 339761 bytes/secmsecs/coect: 0.0473873 mea, 1.155 max, 0.019 mimsecs/first-respose: 29.6366 mea, 51.736 max, 15.22 miHTTP respose codes:code 200 -- 20000-bash: history: write error: Success

2个worker进程

./http_load -fetches 20000 -parallel 100 9502.listasyc 20000 fetches, 100 max parallel, 2.02e+06 bytes, i 3.17119 secods101 mea bytes/coectio6306.77 fetches/sec, 636984 bytes/secmsecs/coect: 0.0643583 mea, 1.211 max, 0.023 mimsecs/first-respose: 15.7489 mea, 32.425 max, 3.242 miHTTP respose codes:code 200 -- 20000-bash: history: write error: Success

4个woker进程

./http_load -fetches 20000 -parallel 100 9502.listasyc 20000 fetches, 100 max parallel, 2.02e+06 bytes, i 1.57194 secods101 mea bytes/coectio12723.2 fetches/sec, 1.28504e+06 bytes/secmsecs/coect: 0.0815263 mea, 1.349 max, 0.02 mimsecs/first-respose: 7.65904 mea, 22.568 max, 1.221 miHTTP respose codes:code 200 -- 20000-bash: history: write error: Success

8个woker进程

./http_load -fetches 20000 -parallel 100 9502.listasyc 20000 fetches, 100 max parallel, 2.02e+06 bytes, i 1.02967 secods101 mea bytes/coectio19423.8 fetches/sec, 1.9618e+06 bytes/secmsecs/coect: 0.147502 mea, 1.575 max, 0.014 mimsecs/first-respose: 3.17218 mea, 22.566 max, 0.339 miHTTP respose codes:code 200 -- 20000-bash: history: write error: Success

功能介绍

php_http_parser 是基于node.js http-parser的PHP扩展,可用于实现纯异步PHP程序 libcurl提供了异步调用方式,有两种风格: ONE MULTI HAND...

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论