本文實例講述了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程序設計有所幫助。