這篇文章主要介紹了PHP封裝的HttpClient類,可實現簡單的GET、POST、Cookie、Session等功能,需要的朋友可以參考下
本文實例講述了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 = !emptyempty ($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程序設計有所幫助。
新聞熱點
疑難解答