PHP封装的HttpClient类用法实例

5年以前  |  阅读数:394 次  |  编程语言:PHP 

本文实例讲述了PHP封装的HttpClient类。分享给大家供大家参考。具体分析如下:

这是一段php封装的HttpClient类,可实现GET POST Cookie Session等简单的功能。原来做过,这两天重新修改了一下。


    <?php 
    /* 
     * Filename: httpclient.php 
     * Created on 2012-12-21 
     * Created by RobinTang 
     * To change the template for this generated file go to 
     * Window - Preferences - PHPeclipse - PHP - Code Templates 
     */ 
    class SinCookie { 
      public $name; // Cookie名称 
      public $value; // Cookie值 
      // 下面三个属性现在未实现 
      public $expires; // 过期时间 
      public $path; // 路径 
      public $domain; // 域 
      // 从Cookie字符串创建一个Cookie对象 
      function __construct($s = false) { 
        if ($s) { 
          $i1 = strpos($s, '='); 
          $i2 = strpos($s, ';'); 
          $this->name = trim(substr($s, 0, $i1)); 
          $this->value = trim(substr($s, $i1 +1, $i2 - $i1 -1)); 
        } 
      } 
      // 获取Cookie键值对 
      function getKeyValue() { 
        return "$this->name=$this->value"; 
      } 
    } 
    // 会话上下文 
    class SinHttpContext { 
      public $cookies; // 会话Cookies 
      public $referer; // 前一个页面地址 
      function __construct() { 
        $this->cookies = array (); 
        $this->refrer = ""; 
      } 
      // 设置Cookie 
      function cookie($key, $val) { 
        $ck = new SinCookie(); 
        $ck->name = $key; 
        $ck->value = $val; 
        $this->addCookie($ck); 
      } 
      // 添加Cookie 
      function addCookie($ck) { 
        $this->cookies[$ck->name] = $ck; 
      } 
      // 获取Cookies字串,请求时用到 
      function cookiesString() { 
        $res = ''; 
        foreach ($this->cookies as $ck) { 
          $res .= $ck->getKeyValue() . ';'; 
        } 
        return $res; 
      } 
    } 
    // Http请求对象 
    class SinHttpRequest { 
      public $url; // 请求地址 
      public $method = 'GET'; // 请求方法 
      public $host; // 主机 
      public $path; // 路径 
      public $scheme; // 协议,http 
      public $port; // 端口 
      public $header; // 请求头 
      public $body; // 请求正文 
      // 设置头 
      function setHeader($k, $v) { 
        if (!isset ($this->header)) { 
          $this->header = array (); 
        } 
        $this->header[$k] = $v; 
      } 
      // 获取请求字符串 
      // 包含头和请求正文 
      // 获取之后直接写socket就行 
      function reqString() { 
        $matches = parse_url($this->url); 
        !isset ($matches['host']) && $matches['host'] = ''; 
        !isset ($matches['path']) && $matches['path'] = ''; 
        !isset ($matches['query']) && $matches['query'] = ''; 
        !isset ($matches['port']) && $matches['port'] = ''; 
        $host = $matches['host']; 
        $path = $matches['path'] ? $matches['path'] . ($matches['query'] ? '?' . $matches['query'] : '') : '/'; 
        $port = !empty ($matches['port']) ? $matches['port'] : 80; 
        $scheme = $matches['scheme'] ? $matches['scheme'] : 'http'; 
        $this->host = $host; 
        $this->path = $path; 
        $this->scheme = $scheme; 
        $this->port = $port; 
        $method = strtoupper($this->method); 
        $res = "$method $path HTTP/1.1\r\n"; 
        $res .= "Host: $host\r\n"; 
        if ($this->header) { 
          reset($this->header); 
          while (list ($k, $v) = each($this->header)) { 
            if (isset ($v) && strlen($v) > 0) 
              $res .= "$k: $v\r\n"; 
          } 
        } 
        $res .= "\r\n"; 
        if ($this->body) { 
          $res .= $this->body; 
          $res .= "\r\n\r\n"; 
        } 
        return $res; 
      } 
    } 
    // Http响应 
    class SinHttpResponse { 
      public $scheme; // 协议 
      public $stasus; // 状态,成功的时候是ok 
      public $code; // 状态码,成功的时候是200 
      public $header; // 响应头 
      public $body; // 响应正文 
      function __construct() { 
        $this->header = array (); 
        $this->body = null; 
      } 
      function setHeader($key, $val) { 
        $this->header[$key] = $val; 
      } 
    } 
    // HttpClient 
    class SinHttpClient { 
      public $keepcontext = true; // 是否维持会话 
      public $context; // 上下文 
      public $request; // 请求 
      public $response; // 响应 
      public $debug = false;
      // 是否在Debug模式,
      //为true的时候会打印出请求内容和相同的头部 
      function __construct() { 
        $this->request = new SinHttpRequest(); 
        $this->response = new SinHttpResponse(); 
        $this->context = new SinHttpContext(); 
        $this->timeout = 15; // 默认的超时为15s 
      } 
      // 清除上一次的请求内容 
      function clearRequest() { 
        $this->request->body = ''; 
        $this->request->setHeader('Content-Length', false); 
        $this->request->setHeader('Content-Type', false); 
      } 
      // post方法 
      // data为请求的数据 
      // 为键值对的时候模拟表单提交 
      // 其他时候为数据提交,提交的形式为xml 
      // 如有其他需求,请自行扩展 
      function post($url, $data = false) { 
        $this->clearRequest(); 
        if ($data) { 
          if (is_array($data)) { 
            $con = http_build_query($data); 
            $this->request->setHeader('Content-Type', 'application/x-www-form-urlencoded'); 
          } else { 
            $con = $data; 
            $this->request->setHeader('Content-Type', 'text/xml; charset=utf-8'); 
          } 
          $this->request->body = $con; 
          $this->request->method = "POST"; 
          $this->request->setHeader('Content-Length', strlen($con)); 
        } 
        $this->startRequest($url); 
      } 
      // get方法 
      function get($url) { 
        $this->clearRequest(); 
        $this->request->method = "GET"; 
        $this->startRequest($url); 
      } 
      // 该方法为内部调用方法,不用直接调用 
      function startRequest($url) { 
        $this->request->url = $url; 
        if ($this->keepcontext) { 
          // 如果保存上下文的话设置相关信息 
          $this->request->setHeader('Referer', $this->context->refrer); 
          $cks = $this->context->cookiesString(); 
          if (strlen($cks) > 0) 
            $this->request->setHeader('Cookie', $cks); 
        } 
        // 获取请求内容 
        $reqstring = $this->request->reqString(); 
        if ($this->debug) 
          echo "Request:\n$reqstring\n"; 
        try { 
          $fp = fsockopen($this->request->host, $this->request->port, $errno, $errstr, $this->timeout); 
        } catch (Exception $ex) { 
          echo $ex->getMessage(); 
          exit (0); 
        } 
        if ($fp) { 
          stream_set_blocking($fp, true); 
          stream_set_timeout($fp, $this->timeout); 
          // 写数据 
          fwrite($fp, $reqstring); 
          $status = stream_get_meta_data($fp); 
          if (!$status['timed_out']) { //未超时 
            // 下面的循环用来读取响应头部 
            while (!feof($fp)) { 
              $h = fgets($fp); 
              if ($this->debug) 
                echo $h; 
              if ($h && ($h == "\r\n" || $h == "\n")) 
                break; 
              $pos = strpos($h, ':'); 
              if ($pos) { 
                $k = strtolower(trim(substr($h, 0, $pos))); 
                $v = trim(substr($h, $pos +1)); 
                if ($k == 'set-cookie') { 
                  // 更新Cookie 
                  if ($this->keepcontext) { 
                    $this->context->addCookie(new SinCookie($v)); 
                  } 
                } else { 
                  // 添加到头里面去 
                  $this->response->setHeader($k, $v); 
                } 
              } else { 
                // 第一行数据 
                // 解析响应状态 
                $preg = '/^(\S*) (\S*) (.*)$/'; 
                preg_match_all($preg, $h, $arr); 
                isset ($arr[1][0]) & $this->response->scheme = trim($arr[1][0]); 
                isset ($arr[2][0]) & $this->response->stasus = trim($arr[2][0]); 
                isset ($arr[3][0]) & $this->response->code = trim($arr[3][0]); 
              } 
            } 
            // 获取响应正文长度 
            $len = (int) $this->response->header['content-length']; 
            $res = ''; 
            // 下面的循环读取正文 
            while (!feof($fp) && $len > 0) { 
              $c = fread($fp, $len); 
              $res .= $c; 
              $len -= strlen($c); 
            } 
            $this->response->body = $res; 
          } 
          // 关闭Socket 
          fclose($fp); 
          // 把返回保存到上下文维持中 
          $this->context->refrer = $url; 
        } 
      } 
    } 
    // demo 
    // now let begin test it 
    $client = new SinHttpClient(); // create a client 
    $client->get('http://www.baidu.com/');  // get 
    echo $client->response->body; // echo 
    ?>

希望本文所述对大家的php程序设计有所帮助。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
获取IMEI
文件下载
贪吃蛇
双位运算符
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
发送邮件
年的日历图
提取后缀名
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例