這裏給你們分享一段使用PHP Socket 編程模擬Http post和get請求的代碼,很是的實用,結尾部分咱們再討論下php模擬http請求的幾種方法。php
<?php /** * 使用PHP Socket 編程模擬Http post和get請求 * @author koma */ class Http{ private $sp = "\r\n"; //這裏必需要寫成雙引號 private $protocol = 'HTTP/1.1'; private $requestLine = ""; private $requestHeader = ""; private $requestBody = ""; private $requestInfo = ""; private $fp = null; private $urlinfo = null; private $header = array(); private $body = ""; private $responseInfo = ""; private static $http = null; //Http對象單例 private function __construct() {} public static function create() { if ( self::$http === null ) { self::$http = new Http(); } return self::$http; } public function init($url) { $this->parseurl($url); $this->header['Host'] = $this->urlinfo['host']; return $this; } public function get($header = array()) { $this->header = array_merge($this->header, $header); return $this->request('GET'); } public function post($header = array(), $body = array()) { $this->header = array_merge($this->header, $header); if ( !empty($body) ) { $this->body = http_build_query($body); $this->header['Content-Type'] = 'application/x-www-form-urlencoded'; $this->header['Content-Length'] = strlen($this->body); } return $this->request('POST'); } private function request($method) { $header = ""; $this->requestLine = $method.' '.$this->urlinfo['path'].'?'.$this->urlinfo['query'].' '.$this->protocol; foreach ( $this->header as $key => $value ) { $header .= $header == "" ? $key.':'.$value : $this->sp.$key.':'.$value; } $this->requestHeader = $header.$this->sp.$this->sp; $this->requestInfo = $this->requestLine.$this->sp.$this->requestHeader; if ( $this->body != "" ) { $this->requestInfo .= $this->body; } /* * 注意:這裏的fsockopen中的url參數形式爲"www.xxx.com" * 不可以帶"http://"這種 */ $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; } private function parseurl($url) { $this->urlinfo = parse_url($url); } } // $url = "http://news.163.com/14/1102/01/AA0PFA7Q00014AED.html"; $url = "http://localhost/httppro/post.php"; $http = Http::create()->init($url); /* 發送get請求 echo $http->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', )); */ /* 發送post請求 */ echo $http->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', ), array('username'=>'發一箇中文', 'age'=>22));
php 模擬 http請求html
方法一:利用php的socket編程來直接給接口發送數據來模擬post的操做。web
創建兩個文件post.php,getpost.php
post.php內容以下:編程
<?php $flag = 0; $params = ''; $errno = ''; $errstr = ''; //要post的數據 $argv = array( 'var1'=>'abc', 'var2'=>'how are you , my friend??'); //構造要post的字符串 foreach ($argv as $key=>$value) { if ($flag!=0) { $params .= "&"; $flag = 1; } $params.= $key."="; $params.= urlencode($value); $flag = 1; } $length = strlen($params); //建立socket鏈接 $fp = fsockopen("localhost",81,$errno,$errstr,10) or exit($errstr."--->".$errno); //構造post請求的頭 $header = "POST /flandy/getpost.php HTTP/1.1\r\n"; $header .= "Host:127.0.0.1\r\n"; $header .= "Referer:/flandy/post.php\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: ".$length."\r\n"; $header .= "Connection: Close\r\n\r\n"; //添加post的字符串 $header .= $params."\r\n"; //發送post的數據 fputs($fp,$header); $inheader = 1; while (!feof($fp)) { $line = fgets($fp,1024); //去除請求包的頭只顯示頁面的返回數據 if ($inheader && ($line == "\n" || $line == "\r\n")) { $inheader = 0; } if ($inheader == 0) { echo $line; } } fclose($fp); ?>
getpost.php的內容以下:app
<?php echo "this is the data posted"; echo "<pre>"; print_r($_REQUEST); echo "</pre>"; ?>
結果輸出:curl
this is the data postedArray ( [var1] => abc [var2] => how are you , my friend?? )
以上代碼在本機81端口下已經經過測試。socket
方法二:使用PHP的curl擴展或HttpClient.class.php類,這兩個很是相似,下面簡單的列出curl的實現代碼。
兩個文件post2.php和getpost2.php
post2.php的內容以下:post
<?php $psecode = 'NDE005'; $website = 'www.baidu.com'; $amt = 1; $pwd = 123456; $ch = curl_init(); $curl_url = "http://localhost:81/flandy/getpost2.php?web=" . $website . "&pwd=" . $pwd . "&action=check&pseid=" . $psecode . "&amt=" . $amt; curl_setopt($ch, CURLOPT_URL, $curl_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不直接輸出,返回到變量 $curl_result = curl_exec($ch); $result = explode(',', $curl_result); curl_close($ch); print_r($result); ?>
getpost2.php的內容以下:測試
<?php echo "returndata<br>"; echo "<pre>"; print_r($_REQUEST); echo "</pre>"; ?>
結果輸出:ui
Array ( [0] => returndataArray ( [web] => 'wwwbaiducom' [pwd] => 123456 [action] => check [pseid] => 'NDE005' [amt] => 1 ) )
方法三:這個要藉助第三方類庫HttpClient能夠到這裏下載:http://scripts.incutio.com/httpclient/
<?php require_once 'HttpClient.class.php'; $params = array('web' => 'www.baidu.com', 'pwd' => '123456', 'action' => 'check', 'pseid' => 'NDE005', 'amt' => 1); $pageContents = HttpClient::quickPost('http://localhost:81/flandy/getpost3.php', $params); $result = explode(',', $pageContents); print_r($result); ?>