목차
使用方式
301 Moved
性能
백엔드 개발 PHP 튜토리얼 可用于实现纯异步PHP程序:php_http_parser

可用于实现纯异步PHP程序:php_http_parser

Jun 23, 2016 pm 01:20 PM

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

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

  • ONE MULTI HANDLE MANY EASY HANDLES:加入多个easy handle后执行curl_multi_perform方法。该方法在php curl扩展中有对应实现。但最后一步curl_multi_perform是阻塞的。

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

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

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

使用方式

$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","<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n","<TITLE>301 Moved</TITLE></HEAD><BODY>\n","<h1 id="nbsp-Moved">301 Moved</h1>\n","The document has moved\n","<A HREF=\"http://www.google.com/\">here</A>.\r\n"    ,"<A HREF=\"http://www.google.com/\">here</A>.\r\n"    ,"<A HREF=\"http://www.google.com/\">here</A>.\r\n"    ,"<A HREF=\"http://www.google.com/\">here</A>.\r\n"    ,"<A HREF=\"http://www.google.com/\">here</A>.\r\n","</BODY></HTML>\r\n");$hp = new HttpParser();foreach($buffs as $buff){    $ret = $hp->execute($buff);    if($ret !== false){        echo $ret;        break;    }}
로그인 후 복사

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

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

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 );        }    }}
로그인 후 복사

性能

[web@gz-web01 php_http_parser]$ time /data/server/php/bin/php http_parser.php  2000000real    0m11.489suser    0m11.435ssys 0m0.017s
로그인 후 복사

1个worker进程

./http_load -fetches 20000 -parallel 100 9502.listasync 20000 fetches, 100 max parallel, 2.02e+06 bytes, in 5.94536 seconds101 mean bytes/connection3363.97 fetches/sec, 339761 bytes/secmsecs/connect: 0.0473873 mean, 1.155 max, 0.019 minmsecs/first-response: 29.6366 mean, 51.736 max, 15.22 minHTTP response codes:code 200 -- 20000-bash: history: write error: Success
로그인 후 복사

2个worker进程

./http_load -fetches 20000 -parallel 100 9502.listasync 20000 fetches, 100 max parallel, 2.02e+06 bytes, in 3.17119 seconds101 mean bytes/connection6306.77 fetches/sec, 636984 bytes/secmsecs/connect: 0.0643583 mean, 1.211 max, 0.023 minmsecs/first-response: 15.7489 mean, 32.425 max, 3.242 minHTTP response codes:code 200 -- 20000-bash: history: write error: Success
로그인 후 복사

4个woker进程

./http_load -fetches 20000 -parallel 100 9502.listasync 20000 fetches, 100 max parallel, 2.02e+06 bytes, in 1.57194 seconds101 mean bytes/connection12723.2 fetches/sec, 1.28504e+06 bytes/secmsecs/connect: 0.0815263 mean, 1.349 max, 0.02 minmsecs/first-response: 7.65904 mean, 22.568 max, 1.221 minHTTP response codes:code 200 -- 20000-bash: history: write error: Success
로그인 후 복사

8个woker进程

./http_load -fetches 20000 -parallel 100 9502.listasync 20000 fetches, 100 max parallel, 2.02e+06 bytes, in 1.02967 seconds101 mean bytes/connection19423.8 fetches/sec, 1.9618e+06 bytes/secmsecs/connect: 0.147502 mean, 1.575 max, 0.014 minmsecs/first-response: 3.17218 mean, 22.566 max, 0.339 minHTTP response codes:code 200 -- 20000-bash: history: write error: Success
로그인 후 복사

官方网站:http://www.open-open.com/lib/view/home/1451808838620

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

뜨거운 기사 태그

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) 11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄) Mar 03, 2025 am 10:49 AM

11 최고의 PHP URL 쇼트너 스크립트 (무료 및 프리미엄)

Instagram API 소개 Instagram API 소개 Mar 02, 2025 am 09:32 AM

Instagram API 소개

Laravel의 플래시 세션 데이터로 작업합니다 Laravel의 플래시 세션 데이터로 작업합니다 Mar 12, 2025 pm 05:08 PM

Laravel의 플래시 세션 데이터로 작업합니다

Laravel Back End : Part 2, React가있는 React 앱 구축 Laravel Back End : Part 2, React가있는 React 앱 구축 Mar 04, 2025 am 09:33 AM

Laravel Back End : Part 2, React가있는 React 앱 구축

Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Laravel 테스트에서 단순화 된 HTTP 응답 조롱 Mar 12, 2025 pm 05:09 PM

Laravel 테스트에서 단순화 된 HTTP 응답 조롱

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법 Mar 14, 2025 am 11:42 AM

PHP의 컬 : REST API에서 PHP Curl Extension 사용 방법

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트 Mar 13, 2025 pm 12:08 PM

Codecanyon에서 12 개의 최고의 PHP 채팅 스크립트

라 라벨에서 알림 라 라벨에서 알림 Mar 04, 2025 am 09:22 AM

라 라벨에서 알림

See all articles