携程接口示例

本文介绍了一个PHP类HttpRequest,用于处理HTTP请求。该类支持GET和POST方法,并可通过socket或fsockopen进行连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<?php
/*
HttpRequest Class
*/
class HttpRequest{
	public $url,$method,$port,$hostname,$uri,$protocol,$excption,$_headers=array(),$_senddata,$status,$statusText,$HttpProtocolVersion,$responseBodyWithoutHeader;
	private $fp=0,$_buffer="",$responseBody,$responseHeader,$timeout=0,$useSocket;
	//构造函数
	function __construct($url="",$method="GET",$useSocket=0){
		$this->url = $url;
		$this->method = strtoupper($method);
		$this->useSocket = $useSocket;
		$this->setRequestHeader("Accept","*/*");
		$this->setRequestHeader("Accept-Language","zh-cn");
		$this->setRequestHeader("Accept-Encoding","gzip, deflate");
		$this->setRequestHeader("User-Agent","HttpRequest Class 1.0");  //可调用setRequestHeader来修改
	}

	//连接服务器
	public function open($ip="",$port=-1){
		if(!$this->_geturlinfo()) return false;
		$this->setRequestHeader("Host",$this->hostname);
		$this->setRequestHeader("Connection","close");
		$ip = ($ip=="" ? $this->hostname : $ip);
		$port = ($port==-1 ? $this->port : $port);
		if($this->useSocket==1){
			if(!$this->fp=$socket=socket_create(AF_INET,SOCK_STREAM,0)) {
				$this->excption="can not create socket";return false;
			}else{
				if(!socket_connect($this->fp,$ip, $port)	){
					$this->excption="can not connect to server " . $this->hostname . " on port" . $this->port;return false;
				}
			}
		}else{
			if(!$this->fp=fsockopen($ip, $port,$errno,$errstr,10)) {
				$this->excption="can not connect to server " . $this->hostname . " on port" . $this->port;return false;
			}
		}
		return true;
	}

	public function send($data=""){
		if(!$this->fp){$this->excption="is not a resource id";return false;}
		if($this->method=="GET" && $data!=""){
			$s_str="?";
			if(strpos($this->uri,"?")>0) $s_str = "&";
			$this->uri.= $s_str . $data;
			$data="";
		}
		$senddata=$this->method . " " . $this->uri . " HTTP/1.1\r\n";
		if($this->method=="POST"){
			$this->setRequestHeader("Content-Length",strlen($data));
			//为了让PHP可以调用API2.0的接口,这边做了修改2012-06-28 CLTANG
			$this->setRequestHeader("Content-Type", "text/xml; charset=utf-8");//application/x-www-form-urlencoded
		}
		foreach($this->_headers as $keys => $value){
			$senddata .= "$keys: $value\r\n";
		}
		$senddata .= "\r\n";
		if($this->method=="POST") $senddata .= $data;
		$this->_senddata = $senddata;
		if($this->useSocket==1){
			socket_write($this->fp,$this->_senddata);
			$buffer="";
			$timestart = time();
			do{
				if($this->timeout>0){
					if(time()-$timestart>$this->timeout){break;}
				}
				$this->_buffer.=$buffer;
				$buffer = socket_read($this->fp,4096);
			}while($buffer!="");
			socket_close($this->fp);
		}else{
			fputs($this->fp, $senddata);
			$this->_buffer="";
			$timestart = time();
			while(!feof($this->fp))
			{
				if($this->timeout>0){
					if(time()-$timestart>$this->timeout){break;}
				}
				$this->_buffer.=fgets($this->fp,4096);
			}
			fclose($this->fp);
		}
		$this->_splitcontent();
		$this->_getheaderinfo();
	}

	public function getResponseBody(){
		if($this->getResponseHeader("Content-Encoding")=="gzip" && $this->getResponseHeader("Transfer-Encoding")=="chunked"){
			return gzdecode_1(transfer_encoding_chunked_decode($this->responseBody));
		}else if($this->getResponseHeader("Content-Encoding")=="gzip"){
			return gzdecode_1($this->responseBody);
		}else{
			return $this->responseBody;
		}
	}

	public function getAllResponseHeaders(){
		return 	$this->responseHeader;
	}

	public function getResponseHeader($key){
		$key = str_replace("-","\-",$key);
		$headerstr = $this->responseHeader . "\r\n";
		$count = preg_match_all("/\n$key\:(.+?)\r/is",$headerstr,$result,PREG_SET_ORDER);
		if($count>0){
			$returnstr="";
			foreach($result as $key1=>$value){
				if(strtoupper($key)=="SET\-COOKIE"){
					$value[1] = substr($value[1],0,strpos($value[1],";"));
				}
				$returnstr .= ltrim($value[1]) . "; ";
			}
			$returnstr = substr($returnstr,0,strlen($returnstr)-2);
			return $returnstr;
		}else{return "";}
	}

	public function setTimeout($timeout=0){
		$this->timeout = $timeout;
	}

	public function setRequestHeader($key,$value=""){
		$this->_headers[$key]=$value;
	}

	public function removeRequestHeader($key){
		if(count($this->_headers)==0){return;}
		$_temp=array();
		foreach($this->_headers as $keys => $value){
			if($keys!=$key){
				$_temp[$keys]=$value;
			}
		}
		$this->_headers = $_temp;
	}

	//拆分url
	private function _geturlinfo(){
		$url = $this->url;
		$count = preg_match("/^http\:\/\/([^\:\/]+?)(\:(\d+))?\/(.+?)$/is",$url,$result);
		if($count>0){
			$this->uri="/" . $result[4];
		}else{
			$count = preg_match("/^http\:\/\/([^\:\/]+?)(\:(\d+))?(\/)?$/is",$url,$result);
			if($count>0){
				$this->uri="/";
			}
		}
		if($count>0){
			$this->protocol="http";
			$this->hostname=$result[1];
			if(isset($result[2]) && $result[2]!="") {$this->port=intval($result[3]);}else{$this->port=80;}
			return true;
		}else{$this->excption="url format error";return false;}
	}

	private function _splitcontent(){
		$this->responseHeader="";
		$this->responseBody="";//有Header的返回体
		$this->responseBodyWithoutHeader="";//没有header的XML
		$p1 = strpos($this->_buffer,"\r\n\r\n");
		$p2=strpos($this->_buffer,"<?xml");//第一次出现XML标记的位置
		if($p1>0){
			$this->responseHeader = substr($this->_buffer,0,$p1);
			if($p1+4<strlen($this->_buffer)){
				$this->responseBody = substr($this->_buffer,$p1+4);
			}
		}
	if($p2>1){//构建只有XML的返回体
			if($p2-1<strlen($this->_buffer)){
				$this->responseBodyWithoutHeader = substr($this->_buffer,$p2-1);
			}
		}
	}

	private function _getheaderinfo(){
		$headerstr = $this->responseHeader;
		$count = preg_match("/^HTTP\/(.+?)\s(\d+)\s(.+?)\r\n/is",$headerstr,$result);
		if($count>0){
			$this->HttpProtocolVersion = $result[1];
			$this->status = intval($result[2]);
			$this->statusText = $result[3];
		}
	}
}


//以下两函数参考网络
function gzdecode_1 ($data) {
	$data = ($data);
	if (!function_exists ( 'gzdecode' )) {
		$flags = ord ( substr ( $data, 3, 1 ) );
		$headerlen = 10;
		$extralen = 0;
		$filenamelen = 0;
		if ($flags & 4) {
			$extralen = unpack ( 'v', substr ( $data, 10, 2 ) );
			$extralen = $extralen [1];
			$headerlen += 2 + $extralen;
		}
		if ($flags & 8) // Filename
			$headerlen = strpos ( $data, chr ( 0 ), $headerlen ) + 1;
		if ($flags & 16) // Comment
			$headerlen = strpos ( $data, chr ( 0 ), $headerlen ) + 1;
		if ($flags & 2) // CRC at end of file
			$headerlen += 2;
		$unpacked = @gzinflate ( substr ( $data, $headerlen ) );
		if ($unpacked === FALSE)
			$unpacked = $data;
		return $unpacked;
	}else{
		return gzdecode($data);
	}
}

function transfer_encoding_chunked_decode($in) {
	$out = "";
	while ( $in !="") {
		$lf_pos = strpos ( $in, "\012" );
		if ($lf_pos === false) {
			$out .= $in;
			break;
		}
		$chunk_hex = trim ( substr ( $in, 0, $lf_pos ) );
		$sc_pos = strpos ( $chunk_hex, ';' );
		if ($sc_pos !== false)
			$chunk_hex = substr ( $chunk_hex, 0, $sc_pos );
		if ($chunk_hex =="") {
			$out .= substr ( $in, 0, $lf_pos );
			$in = substr ( $in, $lf_pos + 1 );
			continue;
		}
		$chunk_len = hexdec ( $chunk_hex );
		if ($chunk_len) {
			$out .= substr ( $in, $lf_pos + 1, $chunk_len );
			$in = substr ( $in, $lf_pos + 2 + $chunk_len );
		} else {
			$in = "";
		}
	}
	return $out;
}
function utf8ToGB_bak($str){
	return iconv("utf-8","gbk",$str);
}

function gbToUtf8_bak($str){
	return iconv("gbk","utf-8",$str);
}

?>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值