使用file_get_contents提交http post

以前使用curl獲取需要登陸內容的文章,但其實,自5.0開始,使用file_get_contents就可以完成.(前提是開啓了allow_url_fopen),下面以一個簡單的例子說明一下:
1.先看一下目標網頁(假設是http://localhost/response.php)
response.php

<?php  
 echo "<pre>";  
 print_r($_POST);  
 print_r($_COOKIE);  
?>


本文講述的只是http post請求的發送,所以,目標頁只是回顯所收到的post和cookie


2.請求頁
request.php

<?
 $data = array("name" => 'tim',"content" => 'test');  
 $data = http_build_query($data);  
 $opts = array(  
   'http'=>array(  
     'method'=>"POST",  
     'header'=>"Content-type: application/x-www-form-urlencoded\r\n".  
               "Content-length:".strlen($data)."\r\n" .   
               "Cookie: foo=bar\r\n" .   
               "\r\n",  
     'content' => $data,  
   )  
 );  
 $cxContext = stream_context_create($opts);  
 $sFile = file_get_contents("http://localhost/response.php", false, $cxContext);  
 
 echo $sFile;  
 
 ?>


這個文件首先使用stream_context_create()構造了一個http請求,然後使用file_get_contents發送出去,返回的結果是:

 
Array
 (  
     [name] => tim  
     [content] => test  
 )  
 Array  
 (  
     [foo] => bar  
 )

所以上可以看出,只要你瞭解http協議,完全可以使用這兩個函數構造出所有正常的http請求,比如代理,斷點續傳等…

<?php      
$option = array(      
'http' => array(      
'method' => "POST", // 常用 POST 或者 GET      
'header' => "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) \r\n Accept: */*", // Header 域內容,用於定義如 Cookie 之類的信息      
'content' => "domain=www.kalvin.cn&author=kalvin", // POST 時提交的內容      
)      
);      
$xoption = stream_context_create($option); // 生成請求所用的頭信息      
echo $str = file_get_contents("http://www.kalvin.cn", false, $xoption); // 執行請求  
print_r($http_response_header); // 顯示返回的頭信息  
?> 


因爲要用php去向我的虛擬主機管理系統發送開通空間等的請求,需要Post傳值,由於開通空間過程很慢,同時需要延時處理。以下找到了一下file_get_contents的超時處理,網上有人用2個方法解決

在使用file_get_contents函數的時候,經常會出現超時的情況,在這裏要通過查看一下錯誤提示,看看是哪種錯誤,比較常見的是讀取超時,這種情況大家可以通過一些方法來儘量的避免或者解決。這裏就簡單介紹兩種:

一、增加超時的時間限制

這裏需要注意:set_time_limit只是設置你的PHP程序的超時時間,而不是file_get_contents函數讀取URL的超時時間。
我一開始以爲set_time_limit也能影響到file_get_contents,後來經測試,是無效的。真正的修改file_get_contents延時可以用resource $context的timeout參數:

$opts = array(
'http'=>array(
'method'=>"GET",
'timeout'=>60,
)
);

$context = stream_context_create($opts);

$html =file_get_contents('http://www.example.com', false, $context);
fpassthru($fp);


二、一次有延時的話那就多試幾次

有時候失敗是因爲網絡等因素造成,沒有解決辦法,但是可以修改程序,失敗時重試幾次,仍然失敗就放棄,因爲file_get_contents()如果失敗將返回 FALSE,所以可以下面這樣編寫代碼:

$cnt=0;
while($cnt < 3 && ($str=@file_get_contents('http...'))===FALSE) $cnt++;

以上方法對付超時已經OK了。那麼Post呢?細心點有人發現了'method'=>"GET", 對!是不是能設置成post呢?百度找了下相關資料,還真可以!而且有人寫出了山寨版的post傳值函數,如下:

function Post($url, $post = null)
{
     $context = array();

     if (is_array($post))
     {
         ksort($post);

         $context['http'] = array
         (   

             'timeout'=>60,
             'method' => 'POST',
             'content' => http_build_query($post, '', '&'),
         );
     }

     return file_get_contents($url, false, stream_context_create($context));
}

$data = array
(
     'name' => 'test',
     'email' => '[email protected]',
     'submit' => 'submit',
);

echo Post('http://www.yifu.info', $data);


OK , 上面函數完美了,既解決了超時控制又解決了Post傳值。再配合康盛的改良版RC4加密解密算法,做一個安全性很高的webservice就簡單多了。

發佈了41 篇原創文章 · 獲贊 50 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章