PHP封裝的HttpClient類用法實(shí)例
更新時(shí)間:2015年06月17日 09:50:28 作者:RobinTang
這篇文章主要介紹了PHP封裝的HttpClient類,可實(shí)現(xiàn)簡單的GET、POST、Cookie、Session等功能,需要的朋友可以參考下
本文實(shí)例講述了PHP封裝的HttpClient類。分享給大家供大家參考。具體分析如下:
這是一段php封裝的HttpClient類,可實(shí)現(xiàn)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值
// 下面三個(gè)屬性現(xiàn)在未實(shí)現(xiàn)
public $expires; // 過期時(shí)間
public $path; // 路徑
public $domain; // 域
// 從Cookie字符串創(chuàng)建一個(gè)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; // 前一個(gè)頁面地址
function __construct() {
$this->cookies = array ();
$this->refrer = "";
}
// 設(shè)置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字串,請求時(shí)用到
function cookiesString() {
$res = '';
foreach ($this->cookies as $ck) {
$res .= $ck->getKeyValue() . ';';
}
return $res;
}
}
// Http請求對象
class SinHttpRequest {
public $url; // 請求地址
public $method = 'GET'; // 請求方法
public $host; // 主機(jī)
public $path; // 路徑
public $scheme; // 協(xié)議,http
public $port; // 端口
public $header; // 請求頭
public $body; // 請求正文
// 設(shè)置頭
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響應(yīng)
class SinHttpResponse {
public $scheme; // 協(xié)議
public $stasus; // 狀態(tài),成功的時(shí)候是ok
public $code; // 狀態(tài)碼,成功的時(shí)候是200
public $header; // 響應(yīng)頭
public $body; // 響應(yīng)正文
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; // 響應(yīng)
public $debug = false;
// 是否在Debug模式,
//為true的時(shí)候會打印出請求內(nèi)容和相同的頭部
function __construct() {
$this->request = new SinHttpRequest();
$this->response = new SinHttpResponse();
$this->context = new SinHttpContext();
$this->timeout = 15; // 默認(rèn)的超時(shí)為15s
}
// 清除上一次的請求內(nèi)容
function clearRequest() {
$this->request->body = '';
$this->request->setHeader('Content-Length', false);
$this->request->setHeader('Content-Type', false);
}
// post方法
// data為請求的數(shù)據(jù)
// 為鍵值對的時(shí)候模擬表單提交
// 其他時(shí)候?yàn)閿?shù)據(jù)提交,提交的形式為xml
// 如有其他需求,請自行擴(kuò)展
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);
}
// 該方法為內(nèi)部調(diào)用方法,不用直接調(diào)用
function startRequest($url) {
$this->request->url = $url;
if ($this->keepcontext) {
// 如果保存上下文的話設(shè)置相關(guān)信息
$this->request->setHeader('Referer', $this->context->refrer);
$cks = $this->context->cookiesString();
if (strlen($cks) > 0)
$this->request->setHeader('Cookie', $cks);
}
// 獲取請求內(nèi)容
$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);
// 寫數(shù)據(jù)
fwrite($fp, $reqstring);
$status = stream_get_meta_data($fp);
if (!$status['timed_out']) { //未超時(shí)
// 下面的循環(huán)用來讀取響應(yīng)頭部
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 {
// 第一行數(shù)據(jù)
// 解析響應(yīng)狀態(tài)
$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]);
}
}
// 獲取響應(yīng)正文長度
$len = (int) $this->response->header['content-length'];
$res = '';
// 下面的循環(huán)讀取正文
while (!feof($fp) && $len > 0) {
$c = fread($fp, $len);
$res .= $c;
$len -= strlen($c);
}
$this->response->body = $res;
}
// 關(guān)閉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程序設(shè)計(jì)有所幫助。
相關(guān)文章
PHP實(shí)現(xiàn)多進(jìn)程并行操作的詳解(可做守護(hù)進(jìn)程)
本篇文章是對PHP實(shí)現(xiàn)多進(jìn)程并行操作進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
用PHP中的 == 運(yùn)算符進(jìn)行字符串比較
用PHP中的 == 運(yùn)算符進(jìn)行字符串比較...2006-11-11
php獲取本機(jī)真實(shí)IP地址實(shí)例代碼
這篇文章主要為大家詳細(xì)介紹了php獲取本機(jī)真實(shí)IP地址實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
PHP實(shí)現(xiàn)統(tǒng)計(jì)代碼行數(shù)小工具
這篇文章主要為大家詳細(xì)介紹了PHP實(shí)現(xiàn)統(tǒng)計(jì)代碼行數(shù)小工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
PHP Session_Regenerate_ID函數(shù)雙釋放內(nèi)存破壞漏洞
PHP Session_Regenerate_ID函數(shù)存在雙釋放內(nèi)容破壞問題,遠(yuǎn)程攻擊者可利用此漏洞對應(yīng)用程序進(jìn)行拒絕服務(wù)攻擊,可能導(dǎo)致任意指令執(zhí)行。2011-01-01

