1. 用 file_get_contents 以 get 方式獲取內容:
1 |
//
$url = 'http://www.nowamagic.net'; |
2 |
$url = 'http://www.nowamagic.net/php/sock.php' ; |
3 |
$html = file_get_contents ( $url ); |
4 |
echo $html ; |
2. 用fopen打開url,以get方式獲取內容
01 |
//
$url = 'http://www.nowamagic.net'; |
02 |
$url = 'http://www.nowamagic.net/php/sock.php' ; |
03 |
$fp = fopen ( $url , 'r' ); |
04 |
stream_get_meta_data( $fp ); |
05 |
$result = '' ; |
06 |
while (! feof ( $fp )) |
07 |
{ |
08 |
$result .= fgets ( $fp ,
1024); |
09 |
} |
10 |
echo "url
body: $result" ; |
11 |
fclose( $fp ); |
3. 用file_get_contents函數,以post方式獲取url
這種方法我們之前點了一下,具體可以參考 stream_context_create()模擬POST/GET 這篇文章。
01 |
$data = array ( |
02 |
'foo' => 'bar' , |
03 |
'baz' => 'boom' , |
04 |
'site' => 'www.nowamagic.net' , |
05 |
'name' => 'nowa
magic' ); |
06 |
|
07 |
$data =
http_build_query( $data ); |
08 |
09 |
//$postdata
= http_build_query($data); |
10 |
$options = array ( |
11 |
'http' => array ( |
12 |
'method' => 'POST' , |
13 |
'header' => 'Content-type:application/x-www-form-urlencoded' , |
14 |
'content' => $data |
15 |
//'timeout'
=> 60 * 60 // 超時時間(單位:s) |
16 |
) |
17 |
); |
18 |
19 |
$url = "http://www.nowamagic.net/test2.php" ; |
20 |
$context =
stream_context_create( $options ); |
21 |
$result = file_get_contents ( $url ,
false, $context ); |
22 |
23 |
echo $result ; |
4. 用 fsockopen 函數打開url,以get方式獲取完整的數據,包括header和body
這種方法在小節前面談得很多了,這裏不厭其煩地再列舉一下:
01 |
//
$url = 'http://www.nowamagic.net'; |
03 |
function get_url( $url , $cookie =false) |
04 |
{ |
05 |
$url = parse_url ( $url ); |
06 |
$query = $url [ 'path' ]. "?" . $url [ 'query' ]; |
07 |
echo "Query:" . $query ; |
08 |
$fp = fsockopen ( $url [ 'host' ], $url [ 'port' ]? $url [ 'port' ]:80
, $errno , $errstr ,
30); |
09 |
if (! $fp ) |
10 |
{ |
11 |
return false; |
12 |
} |
13 |
else { |
14 |
$request = "GET
$query HTTP/1.1\r\n" ; |
15 |
$request .= "Host:
$url[host]\r\n" ; |
16 |
$request .= "Connection:
Close\r\n" ; |
17 |
if ( $cookie ) $request .= "Cookie:
$cookie\n" ; |
18 |
$request .= "\r\n" ; |
19 |
fwrite( $fp , $request ); |
20 |
$result = '' ; |
21 |
while (! feof ( $fp )) |
22 |
{ |
23 |
$result .=
@ fgets ( $fp ,
1024); |
24 |
} |
25 |
fclose( $fp ); |
26 |
return $result ; |
27 |
} |
28 |
} |
29 |
//獲取url的html部分,去掉header |
30 |
function GetUrlHTML( $url , $cookie =false) |
31 |
{ |
32 |
$rowdata =
get_url( $url , $cookie ); |
33 |
if ( $rowdata ) |
34 |
{ |
35 |
$body = stristr ( $rowdata , "\r\n\r\n" ); |
36 |
$body = substr ( $body ,4, strlen ( $body )); |
37 |
return $body ; |
38 |
} |
39 |
40 |
return false; |
41 |
} |
42 |
43 |
echo get_url( $url ); |
44 |
45 |
echo GetUrlHTML( $url ); |
程序輸出:
01 |
Query:/php/sock.php?site=nowamagic.netHTTP/1.1
200 OK |
02 |
Date :
Wed, 19 Feb 2014 06:06:25 GMT |
03 |
Server:
Apache/2.2.3 (CentOS) |
04 |
X-Powered-By:
PHP/5.3.3 |
05 |
Vary:
Accept-Encoding |
06 |
Content-Length:
21 |
07 |
Connection:
close |
08 |
Content-Type:
text/html; charset=UTF-8 |
09 |
10 |
Welcome
to NowaMagic |
11 |
12 |
Query:/php/sock.php?site=nowamagic.net
Welcome to NowaMagic |
5. 用fsockopen函數打開url,以POST方式獲取完整的數據,包括header和body
01 |
//
$url = 'http://www.nowamagic.net'; |
03 |
function HTTP_Post( $URL , $data , $cookie , $referer = "" ) |
04 |
{ |
05 |
06 |
//
parsing the given URL |
07 |
$URL_Info = parse_url ( $URL ); |
08 |
09 |
//
Building referrer |
10 |
if ( $referer == "" ) //
if not given use this script as referrer |
11 |
$referer = "www.nowamagic.net" ; |
12 |
13 |
//
making string from $data |
14 |
foreach ( $data as $key => $value ) |
15 |
$values []= "$key=" .urlencode( $value ); |
16 |
$data_string =implode( "&" , $values ); |
17 |
18 |
//
Find out which port is needed - if not given use standard (=80) |
19 |
if (!isset( $URL_Info [ "port" ])) |
20 |
$URL_Info [ "port" ]=80; |
21 |
|
22 |
$request = '' ; |
23 |
//
building POST-request: |
24 |
$request .= "POST
" . $URL_Info [ "path" ]. "
HTTP/1.1\n" ; |
25 |
$request .= "Host:
" . $URL_Info [ "host" ]. "\n" ; |
26 |
$request .= "Referer:
$referer\n" ; |
27 |
$request .= "Content-type:
application/x-www-form-urlencoded\n" ; |
28 |
$request .= "Content-length:
" . strlen ( $data_string ). "\n" ; |
29 |
$request .= "Connection:
close\n" ; |
30 |
31 |
$request .= "Cookie:
$cookie\n" ; |
32 |
33 |
$request .= "\n" ; |
34 |
$request .= $data_string . "\n" ; |
35 |
36 |
$fp = fsockopen ( $URL_Info [ "host" ], $URL_Info [ "port" ]); |
37 |
fputs ( $fp , $request ); |
38 |
$result = '' ; |
39 |
while (! feof ( $fp )) |
40 |
{ |
41 |
$result .= fgets ( $fp ,
1024); |
42 |
} |
43 |
fclose( $fp ); |
44 |
45 |
return $result ; |
46 |
} |
47 |
48 |
$data = array ( |
49 |
'foo' => 'bar' , |
50 |
'baz' => 'boom' , |
51 |
'site' => 'www.nowamagic.net' , |
52 |
'name' => 'nowa
magic' ); |
53 |
|
54 |
$cookie = '' ; |
55 |
$referer = 'http://www.nowamagic.net/' ; |
56 |
|
57 |
echo HTTP_Post( $url , $data , $cookie , $referer ); |
程序輸出:
01 |
HTTP/1.1
200 OK |
02 |
Date :
Wed, 19 Feb 2014 06:15:38 GMT |
03 |
Server:
Apache/2.2.3 (CentOS) |
04 |
X-Powered-By:
PHP/5.3.3 |
05 |
Vary:
Accept-Encoding |
06 |
Content-Length:
21 |
07 |
Connection:
close |
08 |
Content-Type:
text/html; charset=UTF-8 |
09 |
10 |
Welcome
to NowaMagic |
6. 使用curl庫,使用curl庫之前,可能需要查看一下php.ini是否已經打開了curl擴展。
使用 curl 代碼比較簡潔,代碼也比較規範,容易理解:
01 |
//
$url = 'http://www.nowamagic.net'; |
03 |
$ch =
curl_init(); |
04 |
$timeout =
5; |
05 |
curl_setopt
( $ch ,
CURLOPT_URL, $url ); |
06 |
curl_setopt
( $ch ,
CURLOPT_RETURNTRANSFER, 1); |
07 |
curl_setopt
( $ch ,
CURLOPT_CONNECTTIMEOUT, $timeout ); |
08 |
$file_contents =
curl_exec( $ch ); |
09 |
curl_close( $ch ); |
10 |
|
11 |
echo $file_contents ; |
fsockopen 是比較底層的調用,屬於網絡系統的socket調用,而curl經過的包裝支持HTTPS認證,HTTP POST方法, HTTP PUT方法, FTP上傳, kerberos認證,HTTP上傳, 代理服務器, cookies, 用戶名/密碼認證, 下載文件斷點續傳,上載文件斷點續傳,http代理服務器管道( proxy tunneling), 甚至它還支持IPv6, socks5代理服務器,,通過http代理服務器上傳文件到FTP服務器等等,功能十分強大。fsockopen 返回的是沒有處理過的數據,包括數據的長度數據內容和數據的結束符。而curl是處理後的內容。
在用戶使用時,curl 更加方便,但其參數很多,配置稍微複雜,fsockopen 則有固定的幾個參數,簡單,但獲取結果可能需要再做處理。
那麼file_get_contents呢?
有些時候用 file_get_contents() 調用外部文件容易超時報錯。curl 效率比 file_get_contents() 和 fsockopen() 高一些,原因是CURL會自動對DNS信息進行緩存。
file_get_contents / curl / fsockopen 在當前所請求環境下選擇性操作,沒有一概而論。
file_get_contents 需要php.ini裏開啓allow_url_fopen,請求http時,使用的是http_fopen_wrapper,不會keeplive的話curl是可以的。 file_get_contents()單個執行效率高,返回沒有頭的信息。
這個是讀取一般文件的時候並沒有什麼問題,但是在讀取遠程問題的時候有可能就會出現問題。 如果是要打一個持續連接,多次請求多個頁面。那麼file_get_contents和fopen就會出問題。 取得的內容也可能會不對。所以做一些類似採集工作的時候,肯定就有問題了。
fsockopen 較底層,可以設置基於UDP或是TCP協議去交互,配置麻煩,不易操作。 返回完整信息。
總之,file_get_contents 和 curl 能幹的,socket都能幹。socket能幹的,curl 就不一定能幹了 。file_get_contents 更多的時候只是去拉取數據。效率比較高也比較簡單。
只討論 curl 與file_get_contents 的話,有這麼一些結論:
- fopen /file_get_contents 每次請求都會重新做DNS查詢,並不對DNS信息進行緩存。但是CURL會自動對DNS信息進行緩存。對同一域名下的網頁或者圖片的請求只需要一次DNS查詢。這大大減少了DNS查詢的次數。所以CURL的性能比fopen /file_get_contents 好很多。
- fopen /file_get_contents在請求HTTP時,使用的是http_fopen_wrapper,不會keeplive。而curl卻可以。這樣在多次請求多個鏈接時,curl效率會好一些。
- fopen / file_get_contents函數會受到php.ini文件中allow_url_open選項配置的影響。如果該配置關閉了,則該函數也就失效了。而curl不受該配置的影響。
- curl可以模擬多種請求,例如:POST數據,表單提交等,用戶可以按照自己的需求來定製請求。而fopen / file_get_contents只能使用get方式獲取數據。
PS:file_get_contents()函數獲取https鏈接內容的時候,需要php 中mod_ssl的支持(或安裝opensll)。
結論就是,curl 效率及穩定都比 file_get_contents() 要好,fsockopen 也很強大,但是比較偏底層。
http://www.nowamagic.net/academy/detail/12220248