php+socket模拟表单发送请求

  1 <?php  
  2 /** 
  3  * http请求类(php + socket) 
  4  * @todo 这里还有很多未完善的地方,仅有简单的get post head请求 
  5  * @author chuangrain@gmail.com 
  6  * @version 1.0.0 
  7  */  
  8   
  9 class HttpClient {  
 10   
 11     const CRLF = "
";        
 12     private $fh = null;       //socket handle  
 13     private $errno = -1;      //socket open error no  
 14     private $errstr = '';     //socket open error message  
 15     private $timeout = 30;    //socket open timeout  
 16     private $line = array();  //request line  
 17     private $header = array();//request header  
 18     private $body = array();  //request body  
 19     private $url = array();   //request url  
 20     private $response = '';   //response  
 21     private $version = '1.1'; //http version  
 22       
 23     public function __construct() {  
 24           
 25     }  
 26       
 27     /** 
 28      * 发送HTTP get请求 
 29      * @access public 
 30      * @param string $url 请求的url 
 31      */  
 32     public function get($url = '') {  
 33         $this->setUrl($url);  
 34         $this->setLine();  
 35         $this->setHeader();  
 36         $this->request();  
 37         return $this->response;  
 38     }  
 39       
 40     /** 
 41      * 发送HTTP post请求 
 42      * @access public 
 43      */  
 44     public function post() {  
 45         $this->setLine('POST');  
 46         $this->request();  
 47         return $this->response;  
 48     }  
 49       
 50     /** 
 51      * HTTP -> HEAD 方法,取得服务器响应一个 HTTP 请求所发送的所有标头 
 52      * @access public 
 53      * @param string $url 请求的url 
 54      * @param int $fmt 数据返回形式,关联数组与普通数组 
 55      * @return array 返回响应头信息 
 56      */  
 57     public function head($url = '', $fmt = 0) {  
 58         $headers = null;  
 59         if (is_string($url)) {  
 60             $headers = get_headers($url, $fmt);  
 61         }  
 62         return $headers;  
 63     }  
 64       
 65     /** 
 66      * 设置要请求的 url 
 67      * @todo 这里未做url验证 
 68      * @access public 
 69      * @param string $url request url 
 70      * @return bool 
 71      */  
 72     public function setUrl($url = '') {  
 73         if (is_string($url)) {  
 74             $this->url = parse_url($url);  
 75             if (!isset($this->url['port'])) {//设置端口  
 76                 $this->url['port'] = 80;  
 77             }  
 78         } else {  
 79             return false;  
 80         }  
 81     }  
 82       
 83     /** 
 84      * 设置HTTP协议的版本 
 85      * @access public 
 86      * @param string $version HTTP版本,default value = 1.1 
 87      * @return bool 如果不在范围内返回false 
 88      */  
 89     public function setVersion($version = "1.1") {  
 90         if ($version == '1.1' || $version == '1.0' || $version == '0.9') {  
 91             $this->version = $version;  
 92         } else {  
 93             return false;  
 94         }  
 95     }  
 96       
 97     /** 
 98      * 设置HTTP请求行 
 99      * @access public 
100      * @param string $method 请求方式 default value = GET 
101      */  
102     private function setLine($method = "GET") {  
103         //请求空:Method URI HttpVersion  
104         if (isset($this->url['query'])) {  
105             $this->line[0] = $method . " " . $this->url['path'] . "?" . $this->url['query'] . " HTTP/" . $this->version;  
106         } else {  
107             $this->line[0] = $method . " " . $this->url['path'] . " HTTP/" . $this->version;  
108         }  
109     }  
110       
111     /** 
112      * 设置HTTP请求头信息 
113      * @access public 
114      * @param array $header 请求头信息 
115      */  
116     public function setHeader($header = null) {  
117         $this->header[0] = "Host: " . $this->url['host'];  
118         if (is_array($header)) {  
119             foreach($header as $k => $v) {  
120                 $this->setHeaderKeyValue($k, $v);  
121             }  
122         }  
123     }  
124       
125     /** 
126      * HTTP请求主体 
127      * @access public 
128      * @param array $body 请求主体 
129      */  
130     public function setBody($body = null) {  
131         if (is_array($body)) {  
132             foreach ($body as $k => $v) {  
133                 $this->setBodyKeyValue($k, $v);  
134             }  
135         }  
136     }  
137       
138     /** 
139      * 单条设置HTTP请求主体 
140      * @access public 
141      * @param string $key 请求主体的键 
142      * @param string $value 请求主体的值 
143      */  
144     public function setBodyKeyValue($key, $value) {  
145         if (is_string($key)) {  
146             $this->body[] = $key . "=" . $value;  
147         }  
148     }  
149       
150     /** 
151      * 单条设置HTTP请求头信息 
152      * @access public 
153      * @param string $key 请求头信息的键 
154      * @param string $value 请求头信息的键 
155      */  
156     public function setHeaderKeyValue($key, $value) {  
157         if (is_string($key)) {  
158             $this->header[] = $key . ": " . $value;  
159         }  
160     }  
161       
162     /** 
163      * socket连接host, 发送请求 
164      * @access private 
165      */  
166     private function request() {  
167         //构造http请求  
168         if (!empty($this->body)) {  
169             $bodyStr = implode("&", $this->body);  
170             $this->setHeaderKeyValue("Content-Length", strlen($bodyStr));  
171             $this->body[] = $bodyStr;  
172             $req = array_merge($this->line, $this->header, array(""), array($bodyStr), array(""));  
173         } else {  
174             $req = array_merge($this->line, $this->header, array(""), $this->body, array(""));  
175         }  
176         $req = implode(self::CRLF, $req);  
177           
178         //socket连接host  
179         $this->fh = fsockopen($this->url['host'], $this->url['port'], $this->errno, $this->errstr, $this->timeout);  
180           
181         if (!$this->fh) {  
182             echo "socket connect fail!";  
183             return false;  
184         }  
185           
186         //写请求  
187         fwrite($this->fh, $req);  
188           
189         //读响应  
190         while (!feof($this->fh)) {  
191             $this->response .= fread($this->fh, 1024);  
192         }  
193     }  
194       
195     /** 
196      * 关闭socket连接 
197      * @access public 
198      */  
199     public function __destruct() {  
200         if ($this->fh) {  
201             fclose($this->fh);  
202         }  
203     }  
204       
205 }  
206   
207   
208 $url = "http://localhost/xdebug/post_test.php";  
209   
210 /** get test **/  
211 $http1 = new HttpClient();  
212 var_dump($http1->get($url));  
213   
214 /** post test **/  
215 $http2 = new HttpClient();  
216 $header = array(  
217     "Content-Type" => "application/x-www-form-urlencoded"  
218 );  
219 $body = array(  
220     "username" => "1234",  
221     "submit" => "Login"  
222 );  
223 $http2->setUrl($url);  
224 $http2->setHeader($header);  
225 $http2->setBody($body);  
226 var_dump($http2->post());  
227   
228 /** head test **/  
229 $http3 = new HttpClient();  
230 var_dump($http3->head($url, 1));  
231 post_test.php code list
232 [php] view plaincopyprint?
233 <?php  
234   
235 var_dump($_POST);  
236   
237 ?>  
238   
239 <!DOCTYPE html>  
240 <html>  
241     <head>  
242         <title>post request test</title>  
243     </head>  
244     <body>  
245         <form action="" method="post">  
246             <input type="text" name="username">  
247             <input type="submit" name="submit" value="Login">  
248         </form>  
249     </body>  
250 </html>  
原文地址:https://www.cnblogs.com/linguoguo/p/4043815.html