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设计模式中单例模式的应用分析
May 15 PHP
Yii查询生成器(Query Builder)用法实例教程
Sep 04 PHP
yii2.0实现pathinfo的形式访问的配置方法
Apr 06 PHP
Yii视图CGridView实现操作按钮定义地址示例
Jul 14 PHP
PHP基于curl post实现发送url及相关中文乱码问题解决方法
Nov 25 PHP
PHP中一个有趣的preg_replace函数详解
Aug 15 PHP
PHP设计模式之模板方法模式实例浅析
Dec 20 PHP
PHP Redis扩展无法加载的问题解决方法
Aug 22 PHP
Thinkphp页面跳转设置跳转等待时间的操作
Oct 16 PHP
php使用redis的几种常见操作方式和用法示例
Feb 20 PHP
thinkphp5.1框架模板赋值与变量输出示例
May 25 PHP
浅谈Laravel中使用Slack进行异常通知
May 29 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中实现进程间通讯
2006/10/09 PHP
繁体中文转换为简体中文的PHP函数
2006/10/09 PHP
php下关于Cannot use a scalar value as an array的解决办法
2010/08/08 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
注意!PHP 7中不要做的10件事
2016/09/18 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
js showModalDialog弹出窗口实例详解
2014/01/07 Javascript
jquery获取及设置outerhtml的方法
2015/03/09 Javascript
JavaScript中数据结构与算法(三):链表
2015/06/19 Javascript
详细介绍jQuery.outerWidth() 函数具体用法
2015/07/20 Javascript
javascript对象的创建和访问
2016/03/08 Javascript
简单实现js浮动框
2016/12/13 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
原生JavaScript实现精美的淘宝轮播图效果示例【附demo源码下载】
2017/05/27 Javascript
JS实现的集合去重,交集,并集,差集功能示例
2018/03/13 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
详解Vue中watch的高级用法
2018/05/02 Javascript
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
解决vuex刷新状态初始化的方法实现
2019/08/15 Javascript
老生常谈Python进阶之装饰器
2017/05/11 Python
Python 内置变量和函数的查看及说明介绍
2019/12/25 Python
python如何快速拼接字符串
2020/10/28 Python
求∏的近似值,直到最后一项的绝对值小于指定的数
2016/02/12 面试题
学生出入校管理制度
2014/01/16 职场文书
小学教师培训感言
2014/02/11 职场文书
计算机系统管理员求职信
2014/06/20 职场文书
党政领导班子民主生活会整改措施
2014/09/18 职场文书
意向协议书
2015/01/27 职场文书
绍兴鲁迅故居导游词
2015/02/09 职场文书
人事任命通知
2015/04/20 职场文书
2015年七一建党节活动方案
2015/05/05 职场文书
反邪教警示教育活动总结
2015/05/09 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android
分享CSS盒子模型隐藏的几种方式
2022/02/28 HTML / CSS