0
点赞
收藏
分享

微信扫一扫

PHP HttpClient封装


php封装的HttpClient,能实现些简单的功能。原来做过,这两天重新修改了一下。 

<?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://qzone.qq.com/' ); // get

                 

                 $body = $client->response->body;

                 echo $body; // echo

                 ?>

举报

相关推荐

0 条评论