PHP封装的HttpClient类用法实例
本文实例讲述了PHP封装的HttpClient类。分享给大家供大家参考。具体分析如下:
这是一段php封装的HttpClient类,可实现GETPOSTCookieSession等简单的功能。原来做过,这两天重新修改了一下。
<?php
/*
*Filename:httpclient.php
*Createdon2012-12-21
*CreatedbyRobinTang
*Tochangethetemplateforthisgeneratedfilegoto
*Window-Preferences-PHPeclipse-PHP-CodeTemplates
*/
classSinCookie{
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键值对
functiongetKeyValue(){
return"$this->name=$this->value";
}
}
//会话上下文
classSinHttpContext{
public$cookies;//会话Cookies
public$referer;//前一个页面地址
function__construct(){
$this->cookies=array();
$this->refrer="";
}
//设置Cookie
functioncookie($key,$val){
$ck=newSinCookie();
$ck->name=$key;
$ck->value=$val;
$this->addCookie($ck);
}
//添加Cookie
functionaddCookie($ck){
$this->cookies[$ck->name]=$ck;
}
//获取Cookies字串,请求时用到
functioncookiesString(){
$res='';
foreach($this->cookiesas$ck){
$res.=$ck->getKeyValue().';';
}
return$res;
}
}
//Http请求对象
classSinHttpRequest{
public$url;//请求地址
public$method='GET';//请求方法
public$host;//主机
public$path;//路径
public$scheme;//协议,http
public$port;//端口
public$header;//请求头
public$body;//请求正文
//设置头
functionsetHeader($k,$v){
if(!isset($this->header)){
$this->header=array();
}
$this->header[$k]=$v;
}
//获取请求字符串
//包含头和请求正文
//获取之后直接写socket就行
functionreqString(){
$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$pathHTTP/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响应
classSinHttpResponse{
public$scheme;//协议
public$stasus;//状态,成功的时候是ok
public$code;//状态码,成功的时候是200
public$header;//响应头
public$body;//响应正文
function__construct(){
$this->header=array();
$this->body=null;
}
functionsetHeader($key,$val){
$this->header[$key]=$val;
}
}
//HttpClient
classSinHttpClient{
public$keepcontext=true;//是否维持会话
public$context;//上下文
public$request;//请求
public$response;//响应
public$debug=false;
//是否在Debug模式,
//为true的时候会打印出请求内容和相同的头部
function__construct(){
$this->request=newSinHttpRequest();
$this->response=newSinHttpResponse();
$this->context=newSinHttpContext();
$this->timeout=15;//默认的超时为15s
}
//清除上一次的请求内容
functionclearRequest(){
$this->request->body='';
$this->request->setHeader('Content-Length',false);
$this->request->setHeader('Content-Type',false);
}
//post方法
//data为请求的数据
//为键值对的时候模拟表单提交
//其他时候为数据提交,提交的形式为xml
//如有其他需求,请自行扩展
functionpost($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方法
functionget($url){
$this->clearRequest();
$this->request->method="GET";
$this->startRequest($url);
}
//该方法为内部调用方法,不用直接调用
functionstartRequest($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(newSinCookie($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
//nowletbegintestit
$client=newSinHttpClient();//createaclient
$client->get('http://www.baidu.com/');//get
echo$client->response->body;//echo
?>
希望本文所述对大家的php程序设计有所帮助。