温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在PHP中对HttpClient类进行封装

发布时间:2021-02-24 17:11:23 来源:亿速云 阅读:186 作者:Leah 栏目:开发技术

这篇文章将为大家详细讲解有关怎么在PHP中对HttpClient类进行封装,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

具体分析如下:

<?php  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中对HttpClient类进行封装就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI