http--请求工具类
http请求报文内容本身比较简单,今天仿照别人的代码手写了一个请求客户端,目的是加深了解请求都需要哪些部分。
整个http事务大概分为以下流程
- 通过dns解析出ip和端口
- 三次握手建立tcp连接通道
- 客户端开始构造、发送http请求,服务端接收并处理请求,然后构造响应报文返回给客户端
- 断开tcp连接(keep-alive除外)
当然,实际的http事务过程可能更为复杂,并不与目的服务器直接建立连接,中间或许会经历各种各样的代理过程
http请求报文主要结构
- 请求行
方法 资源路径 协议版本
- 请求首部
请求首部键名 对应值
- 请求主体
请求体
下面是有关请求报文构建代码:
<?php //http客户端工具类 class HttpClient { //行分割付 private $sp = "\r\n"; //请求行 private $requestLine = ""; //请求首部 private $requestHeader = ""; //请求首部数组 private $header = []; //请求主体 private $requestBody = ""; //全部请求信息 请求行+请求首部+请求体 private $requestInfo = ""; //暂存请求地址相关信息 private $urlinfo; //存储套接字 private $fp = null; //协议 private $protocol = 'HTTP/1.1'; //存储响应报文 private $responseInfo=""; private static $http = null;// Http对象单例 protected function __construct(){} //单例模式 public static function create(){ if ( self::$http === null ) { self::$http = new HttpClient(); } return self::$http; } //请求的url public function init($url) { $this->urlinfo = parse_url($url); $this->header['Host'] = $this->urlinfo['host']; return $this; } //请求头信息,请求主体信息 public function get($headers = [],$data=[]) { $this->header = array_merge($this->header,$headers); if(count($data)){ $this->urlinfo['path'] = $this->urlinfo['path'].'?'.http_build_query($data); } return $this->request('GET'); } //请求头信息,请求主体信息 public function post($headers = [],$data=[]) { $this->header = array_merge($this->header,$headers); if(count($data)){ $this->requestBody = http_build_query($data); $this->header['Content-Type'] = 'application/x-www-form-urlencoded'; $this->header['Content-Length'] = strlen(http_build_query($data)); } return $this->request('POST'); } private function request($method) { //请求行 $this->requestLine = $method.' '.$this->urlinfo['path'].' '.$this->protocol.$this->sp; //拼接请求有 $header = ""; foreach ($this->header as $key => $value) { $header.=$key.": ".$value.$this->sp; } $this->requestHeader = $header; $this->requestInfo = $this->requestLine.$this->requestHeader.$this->sp; //如果请求主体不为空 if($this->requestBody != ""){ $this->requestInfo.= $this->requestBody; } $port = isset($this->urlinfo['port']) ? isset($this->urlinfo['port']) : '80'; $this->fp = fsockopen($this->urlinfo['host'], $port, $errno, $errstr); if ( !$this->fp ) { echo $errstr.'('.$errno.')'; return false; } if (fwrite($this->fp, $this->requestInfo) ) { $str = ""; while ( !feof($this->fp) ) { $str .= fread($this->fp,1024); } $this->responseInfo = $str; } fclose($this->fp); return $this->responseInfo; } } $url = 'http://www.baidu.com/index.php'; echo HttpClient::create()->init($url)->post(array( 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', 'Content-Type'=>'text/html; charset=utf-8', 'Content-Length'=>20 ),['aaaaaaaaaa'=>'bbbbbbbbbb']); /* echo HttpClient::create()->init($url)->get(array( 'User-Agent' => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36', 'Content-Type'=>'text/html; charset=utf-8', ),['aaaaaaaaaa'=>'bbbbbbbbbb']); */
推荐一个比较简易学习http报文构建过程源码,代码量少,比较适合我这种看代码头疼的人看,哈哈。
http://scripts.incutio.com/httpclient/HttpClient.tar.gz

浙公网安备 33010602011771号