php HttpRequest类

referer = "";
		$hr->cookie = "";
		$hr->timeOut = 30;
		$hr->cacheSize = 2048;
		$RESULT = $hr.action();
		
		$RESULT 格式
		Array ( 
			头部信息
			[HTTP/1.1] => 200 OK 
			[Content-Type] => text/plain 
			[Last-Modified] => Thu, 15 Jun 2017 04:34:27 GMT 
			[Accept-Ranges] => bytes 
			[ETag] => "cd8851ac90e5d21:0" 
			[Server] => Microsoft-IIS/7.5 
			[X-Powered-By] => ASP.NET 
			[Date] => Thu, 15 Jun 2017 06:49:41 GMT 
			[Connection] => close 
			[Content-Length] => 951 
			正文信息
			[Document_Body] => 
			错误信息
			[error] =>  
		)
		
	*/
	class HttpRequest
	{
		/// 主机地址
		private $host = "";
		/// 协议传输方式 GET POST
		private $method = "get";
		/// 端口
		private $port = 0;
		/// 请求路径
		private $path = "";
		/// 请求参数
		private $query = "";
		/// POST方式要传输的数据
		private $postData = null;
		/// Cookie
		Public $cookie = "";
		/// Referer
		Public $referer = "";
		/// 连接超时
		public $timeOut = 5;
		/// 读取缓存大小
		public $cacheSize = 2048;
		/// 是否阻塞模式
		public $blocked = TRUE;
		
		///构造函数,根据参数数量选择对应方法
		function __construct() 
		{ 
			$a = func_get_args(); 
			$i = func_num_args(); 
			if (method_exists($this, $f="__construct".$i)) 
			{ 
				call_user_func_array(array($this,$f),$a); 
			} 
		}
		
		/// 构造函数派生方法
		private function __construct2($Url,$Method)
		{
			$this->parse_base_url($Url,$Method);
		}
		private function __construct3($Url,$Method,$PostData)
		{
			$this->parse_base_url($url,$method);
			$this->$postData = !isset($PostData) ? $PostData : "";
		}
		
		/// URL地址解析
		private function parse_base_url($u,$m)
		{
			$col = parse_url($u);
			!isset($col["host"]) && $col["host"] = "";
			!isset($col["path"]) && $col["path"] = "/";
			!isset($col["query"]) && $col["query"] = "";
			!isset($col["port"]) && $col["port"] = "";
			$this->host = $col["host"];
			$this->port = !empty($col["port"]) ? $col["port"] : 80;
			$this->path = $col["path"];
			if(array_key_exists("query",$col))
			{
				$this->query = !isset($col["query"])?$col["query"]:"";
			}
			$this->method = ($m === "post") ? $m : "get";
		}
		
		/// HTTP头部解析
		private function parse_HTTP_Headers($headerStr)
		{
			$len = $pos = 0;
			$str = $headerStr;
			$reslt = array();
			$split = strpos($str, "\r\n") > 0 ? "\r\n" : "\n";
			$i = 1;
			while($pos < strlen($str))
			{
				
				$key = $val = "";
				$len = stripos($str, " ", $pos) - $pos;
				$key = str_replace(":", "", substr($str, $pos, $len));
				$pos += $len + 1;
				
				$len = stripos($str, $split, $pos) - $pos;
				$val = str_replace($split, "", substr($str, $pos, $len));
				$pos += $len + 2;
				$reslt[$key] = $val;
				if(strlen($str) - $pos == 2)  break;
			}
			return $reslt;
		}
		
		/// 产生请求包
		protected function makeRequestStr()
		{
			$reqStr =($this->method === "get" ? "GET" : "POST")." ".$this->path.$this->query." HTTP/1.1 \r\n";
			$reqStr .="Host: ".$this->host.":".$this->port."\r\n";
			$reqStr .= "Accept: text/html,application/xhtml+xml,application/xml;image/webp,*/*\r\n";
			$reqStr .= "Accept-Language: zh-CN,zh\r\n";
			$reqStr .= "Accept-Encoding: gzip, deflate\r\n";
			$reqStr .=(($this->method === "post") ? "Content-Type: application/x-www-form-urlencoded\r\n" : "");
			$reqStr .="User-Agent: ".$_SERVER["HTTP_USER_AGENT"]."\r\n";
			$reqStr .=(($this->referer === "") ? "" : "Referer: ".$this->referer."\r\n");
			$reqStr .=(($this->cookie != "") ? "Cookie: ".$this->cookie."\r\n" : "");
			$reqStr .=(($this->method === "post") ? "Content-Length: ".strlen($this->postData)."\r\n" : "");
			$reqStr .="Connection: Close\r\n\r\n";
			$reqStr .=($this->method === "post" && !isset($this->postData)) ? $this->postData."\r\n\r\n" : "";
			return $reqStr;
		}
		
		/// gzip解压缩
		public function gzipDecode ($data) {      
			$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;      
		}
		
		/// chunked解码
		public function chunkedDecode($data)  
		{  
			$pos = 0;  
			$temp = '';  
			while($pos < strlen($data))  
			{  
				$len = strpos($data, "/r/n", $pos) - $pos;
				$str = substr($data, $pos, $len);
				$pos += $len + 2;
				$arr = explode(';', $str, 2);
				$len = hexdec($arr[0]);
				$temp .= substr($data, $pos, $len);
				$pos += $len + 2;  
			}  
			return $temp;  
		}
		
		/// 开始连接目标主机发送请求
		public function action()
		{
			$RESULT = array();
			/// 连接目标主机
			$sock = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeOut);  
			if(!$sock)
			{
				/// 连接失败
				$RESULT["error"] = $errstr; 
			}
			else 
			{
				$header = $content = "";  
				/// 设置阻塞模式
				stream_set_blocking($sock, $this->blocked);  
				/// 设置超时
				stream_set_timeout($sock, $this->timeOut);  
				/// 发送请求
				fwrite($sock, $this->makeRequestStr());
				/// 获取连接状态
				$status = stream_get_meta_data($sock);  
				/// 判断是否超时
				if(!$status["timed_out"]) 
				{
					/// 循环读取HTTP头部
					while (!feof($sock)) 
					{  
						$header .= $h = fgets($sock); 					
						if($h && ($h == "\r\n" ||  $h == "\n")) break;  
					}
					/// 解析头部
					$RESULT = $this->parse_HTTP_Headers($header);
					/// 循环读取正文
					while(!feof($sock)) 
					{
						$data = fread($sock, $this->cacheSize);  
						$content .= $data;  
					}
					/// 整合返回结果
					if(array_key_exists("Content-Encoding", $RESULT))
					{
						/// gzip解压缩
						if(strpos($RESULT["Content-Encoding"], "gzip") > -1)
						{
							$RESULT["Document_Body"] = $this->gzipDecode($content);
						}
						/// chunked解码
						if(strpos($RESULT["Content-Encoding"], "chunked") > -1)
						{
							$RESULT["Document_Body"] = $this->chunkedDecode($content);
						}
					}
					else
					{
						/// 未进行任何压缩编码直接返回结果
						$RESULT["Document_Body"] = $content;
					}
					$RESULT["error"] = "";
				}
				else
				{
					/// 发送数据超时
					$RESULT["error"] = "目标主机发送数据超时!";
				}
			}
			/// 关闭连接
			fclose($sock);  
			$sock = null;
			/// 返回结果
			return $RESULT;
		}
	}
?>

你可能感兴趣的:(php)