PHP的3種發送HTTP請求的方式
1.cURL
<?php class IndexController extends ControllerBase { public function indexAction() { $postfields = array(‘name‘=>‘劉的話liudehua‘,‘age‘=>‘199‘); $this->mycurl(‘http://127.0.0.1:8888‘,http_build_query($postfields)); $this->log->debug("fssss");//phpinfo(); die; } public function getHeader(){ echo "getheader<br>"; } public function mycurl($url, $postfields = NULL, $method=‘POST‘){ //$url = "http://127.0.0.1:8888"; $timeout = 10;//超時時間 $connectTimeout = 0;//無限等待 $ssl = substr($url, 0, 8) == "https://" ? true: false; //開始curl $ci = curl_init(); //設置curl使用的HTTP協議,CURL_HTTP_VERSION_NONE(讓curl自己判斷),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1) curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); //curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); //在HTTP請求中包含一個”user-agent”頭的字符串。curl_setopt($ci, CURLOPT_USERAGENT,‘Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15‘); curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $connectTimeout); //在發起連接前等待的時間,如果設置為0,則無限等待 curl_setopt($ci, CURLOPT_TIMEOUT, $timeout); //如果成功只返回TRUE,自動輸出返回的內容。如果失敗返回FALSE curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); //header中“Accept-Encoding: ”部分的內容,支持的編碼格式為:"identity","deflate","gzip"。如果設置為空字符串,則表示支持所有的編碼格式 curl_setopt($ci, CURLOPT_ENCODING, ""); if ($ssl) { curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false); // 信任任何證書 瀏覽器訪問https的時候,瀏覽器會自動加載網站的安全證書進行加密 curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 1); // 檢查證書中是否設置域名 } //避免data數據過長問題 設置一個header中傳輸內容的數組 //curl_setopt($ci, CURLOPT_HTTPHEADER, array(‘Expect:‘)); //curl_setopt($ch, CURLOPT_HTTPHEADER, array(‘Content-Type: application/json‘,‘Content-Length:‘.strlen($curlPost))); //設置一個回調函數,這個函數有兩個參數,第一個是curl的資源句柄,第二個是輸出的header數據。header數據的輸出必須依賴這個函數,返回已寫入的數據大小 curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, ‘getHeader‘)); //如果你想把一個頭包含在輸出中,設置這個選項為一個非零值。 curl_setopt($ci, CURLOPT_HEADER, FALSE); switch ($method) { case ‘POST‘: curl_setopt($ci, CURLOPT_POST, TRUE); if (!empty($postfields)) { curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); } break; case ‘DELETE‘: curl_setopt($ci, CURLOPT_CUSTOMREQUEST, ‘DELETE‘); if (!empty($postfields)) { $url = "{$url}?{$postfields}"; } } curl_setopt($ci, CURLOPT_URL, $url); //發送請求的字符串頭 curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE); $response = curl_exec($ci); $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); if($response === false) { $error = curl_error($ci); echo "發送失敗"; var_export($error); }else{ echo "成功發送:".var_export($response); } curl_close ($ci); } public function setmemAction(){ $mem=new Memcached(); //實例化Memcached類 /* $server= array( array(‘localhost‘,11200), ); */ $isok = $mem->addServer(‘localhost‘,11200); var_dump($mem->getStats());die; $issetm = $mem->set(‘name‘,‘網絡管理nginx‘,0); ////設置緩存值,有效時間3600秒,如果有效時間設置為0,則表示該緩存值永久存在的(系統重啟前) echo $mem->get(‘name‘); } public function getmemAction(){ $mem=new Memcached(); //實例化Memcached類 $server= array( array(‘localhost‘,11200), ); $isok = $mem->addServers($server); var_dump($isok); echo $mem->get(‘name‘); } public function testdbAction(){ $dbhost = ‘localhost:3306‘; // mysql服務器主機地址 $dbuser = ‘daokrdb‘; // mysql用戶名 $dbpass = ‘123456‘; // mysql用戶名密碼 $conn = mysqli_connect($dbhost, $dbuser, $dbpass); if(! $conn ) { die(‘Could not connect: ‘ . mysqli_error()); } echo ‘數據庫連接成功!‘; // 設置編碼,防止中文亂碼 mysqli_query($conn , "set names utf8"); //使用哪個個數據庫 mysqli_select_db( $conn, ‘daokrdb‘ ); $sql = ‘SELECT * FROM t_users‘; $retval = mysqli_query( $conn, $sql ); if(! $retval ) { die(‘無法讀取數據: ‘ . mysqli_error($conn)); } echo ‘<table border="1" width="100%"><tr><td>教程 ID</td><td>標題</td><td>作者</td><td>提交日期</td></tr>‘; while($row = mysqli_fetch_array($retval, MYSQLI_ASSOC)) { echo "<tr><td> {$row[‘id‘]}</td> ". "<td>{$row[‘title‘]} </td> ". "<td>{$row[‘author‘]} </td> ". "<td>{$row[‘submission_date‘]} </td> ". "</tr>"; } echo ‘</table>‘; mysqli_close($conn); } public function redisAction(){ $redis = new Redis(); $redis->connect(‘127.0.0.1‘, 6379); echo "Connection to server sucessfully<br/>"; //存儲數據到列表中 $redis->lpush("tutorial-list", "Redis"); $redis->lpush("tutorial-list", "Mongodb"); $redis->lpush("tutorial-list", "Mysql"); // 獲取存儲的數據並輸出 $arList = $redis->lrange("tutorial-list", 0 ,5); echo "Stored string in redis------<br/>"; echo"壓入隊列:<br/>";var_export($arList); echo "<br/>"; // 獲取列表長度 $llen = $redis->llen(‘tutorial-list‘); while ($llen){ echo "彈出數據:".$redis->lpop(‘tutorial-list‘)."<br/>"; $llen = $redis->llen(‘tutorial-list‘); } // 獲取存儲的數據並輸出 $arList = $redis->lrange("tutorial-list", 0 ,5); echo "Stored string in redis------<br/>"; var_export($arList); } //測試reds public function testredisAction(){ $store=10; $redis=new Redis(); $result=$redis->connect(‘127.0.0.1‘,6379); $res=$redis->llen(‘goods_store‘); echo $res."<br>"; $count=$store-$res; for($i=0;$i<$count;$i++){ $redis->lpush(‘goods_store‘,1); } echo $redis->llen(‘goods_store‘); } public function buyAction(){ //模擬下單操作 //下單前判斷redis隊列庫存量 $redis=new Redis(); $result=$redis->connect(‘127.0.0.1‘,6379); $count=$redis->lpop(‘goods_store‘); echo $count."<br>"; echo $redis->llen(‘goods_store‘)."<br>"; if(!$count){ echo(‘error:no store redis‘); }else{ //生成訂單 $order_sn=$this->build_order_no(); echo $order_sn; } } //生成唯一訂單號 function build_order_no(){ return date(‘ymd‘).substr(implode(NULL, array_map(‘ord‘, str_split(substr(uniqid(), 7, 13), 1))), 0, 8); } //正則表達式 public function pregAction(){ //使用逗號或空格(包含" ", \r, \t, \n, \f)分隔短語 $str = "hypertext language, programming‘name wokd"; $keywords = preg_split("/[\s\‘]+/", $str); print_r($keywords); //替換 $string = ‘language 15, 2003‘; $pattern = ‘/(\w+) (\d+), (\d+)/i‘; $replacement = ‘wangxiaomai 09,$3‘; echo "<br>"; echo preg_replace($pattern, $replacement, $string); echo "<br>"; $array = array("23.32","22","12.009","26666.43.43","88899.777.888.444","g9","Uafdsfasdfadsfsd10","#9");// ? 匹配前面的子表達式零次或一次 print_r(preg_grep("/^(\d+)\.(\d+)\.(\d+)$/",$array)); echo "<br>"; print_r(preg_grep("/^[a-zA-Z]{1,}[0-9]{1,}$/",$array)); //從URL中獲取主機名稱 preg_match(‘@^(?:http://)?([^/]+)@i‘,"http://www.php.net/index.html", $matches); $host = $matches[1]; //獲取主機名稱的後面兩部分 preg_match(‘/[^.]+\.[^.]+$/‘, $host, $matches); echo "domain name is: {$matches[0]}\n"; echo "<br>"; echo gethostname(); } }
2.stream流的方式
stream_context_create — 創建資源流上下文
stream_context_create 作用:創建並返回一個文本數據流並應用各種選項,
可用於 fopen(), file_get_contents() 等過程的超時設置、代理服務器、請求方式、頭信息設置的特殊過程。
例子:
<?php function post($url, $data) { $postdata = http_build_query( $data ); $opts = array(‘http‘ => array( ‘method‘ => ‘POST‘, ‘header‘ => ‘Content-type: application/x-www-form-urlencoded‘, ‘content‘ => $postdata ) ); $context = stream_context_create($opts); $result = file_get_contents($url, false, $context); return $result; }
3.socket方式
使用套接字建立連接,拼接 HTTP 報文發送數據進行 HTTP 請求。
fsockopen — 打開一個網絡連接或者一個Unix套接字連接
說明
resource fsockopen ( string$hostname
[, int $port
= -1 [, int &$errno
[, string &$errstr
[, float $timeout
= ini_get("default_socket_timeout") ]]]] )
初始化一個套接字連接到指定主機(hostname
)。
PHP支持以下的套接字傳輸器類型列表 所支持的套接字傳輸器(Socket Transports)列表。也可以通過stream_get_transports()來獲取套接字傳輸器支持類型。
默認情況下將以阻塞模式開啟套接字連接。當然你可以通過stream_set_blocking()將它轉換到非阻塞模式。
stream_socket_client()與之非常相似,而且提供了更加豐富的參數設置,包括非阻塞模式和提供上下文的的設置。
參數
hostname
-
如果安裝了OpenSSL,那麽你也許應該在你的主機名地址前面添加訪問協議ssl://或者是tls://,從而可以使用基於TCP/IP協議的SSL或者TLS的客戶端連接到遠程主機。
port
-
端口號。如果對該參數傳一個-1,則表示不使用端口,例如unix://。
errno
-
如果傳入了該參數,holds the system level error number that occurred in the system-level connect() call。
如果
errno
的返回值為0,而且這個函數的返回值為FALSE
,那麽這表明該錯誤發生在套接字連接(connect())調用之前,導致連接失敗的原因最大的可能是初始化套接字的時候發生了錯誤。 errstr
-
錯誤信息將以字符串的信息返回。
timeout
-
設置連接的時限,單位為秒。
Note:
註意:如果你要對建立在套接字基礎上的讀寫操作設置操作時間設置連接時限,請使用stream_set_timeout(),fsockopen()的連接時限(
timeout
)的參數僅僅在套接字連接的時候生效。
返回值
fsockopen()將返回一個文件句柄,之後可以被其他文件類函數調用(例如:fgets(),fgetss(),fwrite(),fclose()還有feof())。如果調用失敗,將返回FALSE
。
<?php $fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); while (!feof($fp)) { echo fgets($fp, 128); } fclose($fp); } ?>
用fsockopen 以post方式獲取數據
1 <?php 2 function HTTP_Post($URL,$data,$cookie, $referrer="") 3 { 4 // parsing the given URL 5 $URL_Info=parse_url($URL); 6 // Building referrer 7 if($referrer=="") // if not given use this script as referrer 8 $referrer="111"; 9 // making string from $data 10 foreach($data as $key=>$value) 11 $values[]="$key=".urlencode($value); 12 $data_string=implode("&",$values); 13 // Find out which port is needed - if not given use standard (=80) 14 if(!isset($URL_Info["port"])) 15 $URL_Info["port"]=80; 16 // building POST-request: 17 $request.="POST ".$URL_Info["path"]." HTTP/1.1\n"; 18 $request.="Host: ".$URL_Info["host"]."\n"; 19 $request.="Referer: $referer\n"; 20 $request.="Content-type: application/x-www-form-urlencoded\n"; 21 $request.="Content-length: ".strlen($data_string)."\n"; 22 $request.="Connection: close\n"; 23 $request.="Cookie: $cookie\n"; 24 $request.="\n"; 25 $request.=$data_string."\n"; 26 $fp = fsockopen($URL_Info["host"],$URL_Info["port"]); 27 fputs($fp, $request); 28 while(!feof($fp)) { 29 $result .= fgets($fp, 1024); 30 } 31 fclose($fp); 32 return $result; 33 } 34 ?>
用fsockopen函數打開url,以get方式獲取完整的數據,包括header和body,fsockopen需要 PHP.ini 中
allow_url_fopen 選項開啟
1 <?php 2 function get_url ($url,$cookie=false) 3 { 4 $url = parse_url($url); 5 $query = $url[path]."?".$url[query]; 6 echo "Query:".$query; 7 $fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30); 8 if (!$fp) { 9 return false; 10 } else { 11 $request = "GET $query HTTP/1.1\r\n"; 12 $request .= "Host: $url[host]\r\n"; 13 $request .= "Connection: Close\r\n"; 14 if($cookie) $request.="Cookie: $cookie\n"; 15 $request.="\r\n"; 16 fwrite($fp,$request); 17 while()) { 18 $result .= @fgets($fp, 1024); 19 } 20 fclose($fp); 21 return $result; 22 } 23 } 24 //獲取url的html部分,去掉header 25 function GetUrlHTML($url,$cookie=false) 26 { 27 $rowdata = get_url($url,$cookie); 28 if($rowdata) 29 { 30 $body= stristr($rowdata,"\r\n\r\n"); 31 $body=substr($body,4,strlen($body)); 32 return $body; 33 } 34 return false; 35 } 36 ?>
PHP的3種發送HTTP請求的方式