我的HTTP Client 模拟PHP Class

  •   2009-07-31/22:47
  • 最近因为要通过PHP调用REST接口,简单的写了一个模拟HTTPClient的PHP Class.相当于模拟浏览器操作.这是一个初始版本.等以后有时间了在完善下.如果有什么意见或者好的想法,欢迎指教.

    <?php
    /*
    ===========================================================
        HTTP.php    Zhu Weiwei
        Copyright © 2006-2008
        China. All Rights Reserved.
    ===========================================================
    */

    class HTTP{
        private $m_httpVersion  = "HTTP/1.0";
        private $m_method       = "GET";
        private $m_enctype      = "application/x-www-form-urlencoded";
        private $m_scheme       = "http";
        private $m_host         = "127.0.0.1";
        private $m_port         = 80;
        private $m_path         = "/";
        private $m_query        = "";
        private $m_fragment     = "";
        private $m_user         = "";
        private $m_pass         = "";
        private $m_uri          = "/";

        private $m_referer      = "";
        private $m_mimeBoundary = "";
        private $m_sockTimeout  = 10;
        private $m_readTimeout  = 10;
        private $m_timeout      = false;
       
        private $m_sock         = "";
        private $m_error        = "";
        private $CRLF           = "\r\n";

        private $m_arrParam     = Array();
        private $m_arrFile      = Array();
        private $m_arrCookie    = Array();

        private $m_request      = "";
        private $m_requestHead  = "";
        private $m_requestBody  = "";

        private $m_response     = "";
        private $m_responseHead = Array();
        private $m_responseBody = "";

        private $m_maxLineLength= 1024;

     

        function __construct() {

        }

        function getResponseHead() {
            return $this->m_responseHead;
        }

        function getResponseBody() {
            return $this->m_responseBody;
        }

        function getResponse() {
            return $this->m_response;
        }

        function getRequestHead() {
            return $this->m_requestHead;
        }

        function getRequestBody() {
            return $this->m_requestBody;
        }

        function getRequest() {
            return $this->m_request;
        }

        function getError() {
            return $this->m_error;
        }

        function setMethod($m) {
            $this->m_method = (strtoupper($m=='POST'))?('POST'):('GET');
        }

        function setEnctype($e) {
            $this->m_enctype = (strtolower($e)=='application/x-www-form-urlencoded')?
                                ('application/x-www-form-urlencoded'):('multipart/form-data');
        }

        function setURL($url) {
            $rs = parse_url($url);
            $this->m_scheme   = empty($rs['scheme'])  ?('http')     :($rs['scheme']);
            $this->m_host     = empty($rs['host'])    ?('localhost'):($rs['host']);
            $this->m_port     = empty($rs['port'])    ?('80')       :($rs['port']);
            $this->m_user     = empty($rs['user'])    ?('')         :($rs['user']);
            $this->m_pass     = empty($rs['pass'])    ?('')         :($rs['pass']);
            $this->m_path     = empty($rs['path'])    ?('/')        :($rs['path']);
            $this->m_query    = empty($rs['query'])   ?('')         :($rs['query']);
            $this->m_fragment = empty($rs['fragment'])?('')         :($rs['fragment']);
           
            $this->m_uri = $this->m_path;
            if(!empty($this->m_query)){
                $this->m_uri .= '?'.$this->m_query;
            }
            if(!empty($this->m_fragment)){
                $this->m_uri .= '#'.$this->m_fragment;
            }
        }


        function addParameter($key,$val) {
            if(!empty($key)){
                $this->m_arrParam[$key] = $val;
            }
        }

        function addFile($key,$file) {
            if(!empty($key) && file_exists($file)){
                $this->m_arrFile[$key] = $file;
            }
        }

        function addCookie($key,$val) {
            if(!empty($key)){
                $this->m_arrCookie[$key] = $val;
            }
        }

        function connect() {
            $this->m_sock = fsockopen($this->m_host,
                                      $this->m_port,
                                      $errno,
                                      $errstr,
                                      $this->m_sockTimeout);

            if($this->m_sock){
                return true;
            }else{
                switch($errno){
                    case -3: $this->m_error="socket creation failed (-3)";          break;
                    case -4: $this->m_error="dns lookup failure (-4)";              break;
                    case -5: $this->m_error="connection refused or timed out (-5)"; break;
                    default: $this->m_error="connection failed (".$errno.")";       break;
                }
                return false;
            }
        }

        function disconnect(){
            return(fclose($this->m_sock));
        }


        function sendRequest() {
            if($this->connect()){
                $this->buildRequest();

                socket_set_timeout($this->m_sock, $this->m_readTimeout);
                fwrite($this->m_sock, $this->m_request, strlen($this->m_request));

                /*
                    Get And Parse HTTP Header
                */

                while( !feof($this->m_sock) )
                {
                    if( $this->m_readTimeout > 0 && $this->checkResponseTimeOut() ){
                        return false;
                    }
                    $line = fgets($this->m_sock, $this->m_maxLineLength);
                    if($line == $this->CRLF )
                        break;

                    $this->m_responseHead['Content'] .= $line;
                    if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$line, $status)){
                        $this->m_responseHead['Status'] = $status[1];
                    }else{
                        list($key,$val) = explode(': ',$line,2);
                        $this->m_responseHead[$key] = $val;
                    }
                }

     

                /*
                    Get HTTP Body
                */
                while(!feof($this->m_sock) ) {
                    if( $this->m_readTimeout > 0 && $this->checkResponseTimeOut() ){
                        return false;
                    }
                    $this->m_responseBody .= fgets($this->m_sock, $this->m_maxLineLength);
                }       

                $this->m_response = $this->m_responseHead['Content'].$this->m_responseBody;
                $this->disconnect();
                return true;
            }else{
                return false;
            }
        }

        function checkResponseTimeOut()
        {
            if ($this->m_readTimeout > 0) {
                $fp_status = socket_get_status($this->m_sock);
                if ($fp_status["timed_out"]) {
                    $this->m_error="read response timeout!";
                    return true;
                }
            }
            return false;
        }


        function buildRequest() {
            switch( $this->m_method ){
                case "POST":
                    $body = $this->buildRequestBody();
                    $head = $this->buildRequestHead();

                    $this->m_request = $head.$this->CRLF.$this->CRLF.$body;
                    break;

                case "GET":
                    $head = $this->buildRequestHead();

                    $this->m_request = $head.$this->CRLF.$this->CRLF;
                    break;
            }
            return $this->m_request;
        }


        function buildRequestHead() {
            $header = Array();
            switch( $this->m_method ){
                case "POST":
                    $header[] ="POST $this->m_uri $this->m_httpVersion";
                    $header[] = "Content-Length: ".strlen($this->m_requestBody); 
                    switch ($this->m_enctype) {
                        case "application/x-www-form-urlencoded":
                            $header[] ="Content-Type: application/x-www-form-urlencoded";
                            //$header[] ="Content-Type: application/xml; charset=UTF-8";
                            break;
                        case "multipart/form-data":
                            $header[] ="Content-Type: multipart/form-data; boundary=$this->m_mimeBoundary";    
                            break;
                    }
                    break;
                case "GET":
                    $header[] ="GET $this->m_uri $this->m_httpVersion";
                    break;
            }

            $header[] = "Cache-Control: no-cache";
            $header[] = "Pragma: no-cache";
            $header[] = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11";
            $header[] = "Accept: */*";
            #$header[] = "Accept-Language: zh-cn";
            #$header[] = "Accept-Encoding: gzip,deflate";
            #$header[] = "Accept-Charset: utf-8";
            $header[] = "Connection: Keep-Alive";
            $header[] = "Keep-Alive: 300";

            //$header[] = "Connection: Close";
            //$header[] = "Referer: $this->m_referer";
            //$header[] = "Cookie: ".join(';',$this->m_arrCookie);

            if( intval($this->m_port) == 80 ){
                $header[] = "Host: $this->m_host";
            }else{
                $header[] = "Host: $this->m_host:$this->m_port";
            }

            if(!empty($this->m_user) || !empty($this->m_pass)){   
                $header[] = "Authorization: Basic ".base64_encode($this->m_user.":".$this->m_pass);
            }

            $this->m_requestHead = join($this->CRLF, $header);
            return $this->m_requestHead;
        }


        function buildRequestBody() {
            $body = Array();
            switch ($this->m_enctype) {
                case "application/x-www-form-urlencoded":
                    foreach( $this->m_arrParam as $key=>$val) {
                       $body[] = urlencode($key)."=".urlencode($val);
                    }
                    $this->m_requestBody =  join("&",$body);
                    //$this->m_requestBody = json_encode($this->m_arrParam); //For Rest
                    break;

                case "multipart/form-data":
                    $this->m_mimeBoundary = '<'.base64_encode(uniqid(microtime(),true)).'=>';

                    foreach( $this->m_arrParam as $key=>$val) {
                        $body[] = "--".$this->m_mimeBoundary;
                        $body[] = "Content-Disposition: form-data; name=\"$key\"".$this->CRLF;
                        $body[] = $val;
                    }

                    foreach( $this->m_arrFile as $key=>$filename) {
                        $body[] = "--".$this->m_mimeBoundary;
                        $body[] = "Content-Disposition: form-data; name=\"$key\"; filename=\"$filename\"";
                        $body[] = "Content-Type: application/octet-stream";
                        $body[] = "Content-Transfer-Encoding: Binary".$this->CRLF;
                        $body[] = file_get_contents($filename);
                    }
                    $body[] = "--".$this->m_mimeBoundary."--".$this->CRLF;
                    $this->m_requestBody =  join($this->CRLF,$body);
                    break;
            }
            return $this->m_requestBody;
        }
    };
    example.php

    <?php
    require_once("http.php");
    $oHTTP = new HTTP();
    $oHTTP->setURL("");
    $oHTTP->setMethod("POST");
    $oHTTP->addParameter("param","value");
    $oHTTP->addFile("filedata","/tmp/tmpFile");
    if( !$oHTTP->sendRequest() ){
        print($oHTTP->getError());
        exit();
    }
    $request  = $oHTTP->getRequest();
    $response = $oHTTP->getResponse();
    print($response);


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多