PHP封装的HttpClient类用法实例


Posted in PHP onJune 17, 2015

本文实例讲述了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 相关文章推荐
php字符串截取问题
Nov 28 PHP
利用PHP制作简单的内容采集器的代码
Nov 28 PHP
修改php.ini实现Mysql导入数据库文件最大限制的修改方法
Dec 11 PHP
php 破解防盗链图片函数
Dec 09 PHP
深入PHP中慎用双等于(==)的详解
Jun 06 PHP
PHP反射类ReflectionClass和ReflectionObject的使用方法
Nov 13 PHP
PHP中常用的转义函数
Feb 28 PHP
浅谈使用PHP开发微信支付的流程
Oct 04 PHP
PHP json_encode() 函数详解及中文乱码问题
Nov 05 PHP
Laravel 5.1 on SAE环境开发教程【附项目demo源码】
Oct 09 PHP
PHP常用函数之获取汉字首字母功能示例
Oct 21 PHP
tp5框架使用cookie加密算法实现登录功能示例
Feb 10 PHP
PHP处理postfix邮件内容的方法
Jun 16 #PHP
PHP限制HTML内容中图片必须是本站的方法
Jun 16 #PHP
php采集中国代理服务器网的方法
Jun 16 #PHP
分享php分页的功能模块
Jun 16 #PHP
PHP生成plist数据的方法
Jun 16 #PHP
php动态绑定变量的用法
Jun 16 #PHP
php实现在服务器端调整图片大小的方法
Jun 16 #PHP
You might like
php smtp实现发送邮件功能
2017/06/22 PHP
JavaScript eval() 函数介绍及应用示例
2014/07/29 Javascript
微信小程序 数组中的push与concat的区别
2017/01/05 Javascript
详解Vue中使用Echarts的两种方式
2018/07/03 Javascript
详解vue移动端项目的适配(以mint-ui为例)
2018/08/17 Javascript
jQuery事件委托代码实践详解
2019/06/21 jQuery
Vue中关闭弹窗组件时销毁并隐藏操作
2020/09/01 Javascript
微信小程序实现左滑删除效果
2020/11/18 Javascript
[00:14]护身甲盾
2019/03/06 DOTA
Python计算回文数的方法
2015/03/11 Python
python通过ftplib登录到ftp服务器的方法
2015/05/08 Python
轻松实现python搭建微信公众平台
2016/02/16 Python
python切片及sys.argv[]用法详解
2018/05/25 Python
对python添加模块路径的三种方法总结
2018/10/16 Python
python解析xml简单示例
2019/06/21 Python
Python3+Appium安装使用教程
2019/07/05 Python
numpy创建单位矩阵和对角矩阵的实例
2019/11/29 Python
Python中类似于jquery的pyquery库用法分析
2019/12/02 Python
Python +Selenium解决图片验证码登录或注册问题(推荐)
2020/02/09 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
使用python计算三角形的斜边例子
2020/04/15 Python
Python根据指定文件生成XML的方法
2020/06/29 Python
CSS3实现的闪烁跳跃进度条示例(附源码)
2013/08/19 HTML / CSS
浅谈css3新单位vw、vh、vmin、vmax的使用详解
2017/12/01 HTML / CSS
HTML5 Plus 实现手机APP拍照或相册选择图片上传功能
2016/07/13 HTML / CSS
详解通过HTML5 Canvas实现图片的平移及旋转变化的方法
2016/03/22 HTML / CSS
Lands’ End英国官方网站:高质量男女服装
2017/10/07 全球购物
PHP中如何创建和修改数组
2012/05/02 面试题
Ibatis中如何提高SQL Map的性能
2013/05/11 面试题
经典大学生求职信范文
2014/01/06 职场文书
工程采购员岗位职责
2014/03/09 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
学生保证书
2015/01/16 职场文书
护士岗位竞聘书
2015/09/15 职场文书
600字作文之感受大自然
2019/11/27 职场文书
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers