php HttpRequest类

来源:互联网 发布:java split 问号 编辑:程序博客网 时间:2024/06/14 03:52
<?php/*HttpRequest Classfunction __construct2($Url,$Method)function __construct3($Url,$Method,$PostData)$hr = new HttpRequest("ssl://www.baidu.com:443/", "get");$hr = new HttpRequest("http://www.baidu.com:80/", "get");$hr = new HttpRequest("http://www.baidu.com:80/", "post", $PostData);$hr->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 POSTprivate $method = "get";/// 端口private $port = 0;/// 请求路径private $path = "";/// 请求参数private $query = "";/// POST方式要传输的数据private $postData = null;/// CookiePublic $cookie = "";/// RefererPublic $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;}}?>

原创粉丝点击