PHP CURL與file_get_contents函數都可以獲取遠程服務器上的文件保存到本地,但在性能上面兩者完全不在同一個級別,下面我先來介紹PHP CURL或file_get_contents函數應用例子,然后再簡單的給各位介紹一下它們的一些小區別吧。
推薦方法 CURL獲取
1
|
2
3
4
5
6
7
8
9
10
11
12
|
<?php $c = curl_init(); $url = 'www.zmynmublwnt.cn' ; curl_setopt( $c , CURLOPT_URL, $url ); curl_setopt( $c , CURLOPT_RETURNTRANSFER, 1); $data = curl_exec( $c ); curl_close( $c ); $pos = strpos ( $data , 'utf-8' ); if ( $pos ===false){ $data = iconv( "gbk" , "utf-8" , $data );} preg_match( "/<title>(.*)<\/title>/i" , $data , $title ); echo $title [1]; ?> |
使用file_get_contents
1
|
2
3
4
5
6
7
8
9
|
<?php $content = file_get_contents ( " http://www.zmynmublwnt.cn/ " ); $pos = strpos ( $content , 'utf-8' ); if ( $pos ===false){ $content = iconv( "gbk" , "utf-8" , $content );} $postb = strpos ( $content , '<title>' )+7; $poste = strpos ( $content , '</title>' ); $length = $poste - $postb ; echo substr ( $content , $postb , $length ); ?> |
看看file_get_contents性能
1)fopen/file_get_contents 每次請求遠程URL中的數據都會重新做DNS查詢,并不對DNS信息進行緩存。但是CURL會自動對DNS信息進行緩存。對同一域名下的網頁或者圖片的請求只需要一次DNS 查詢。這大大減少了DNS查詢的次數。所以CURL的性能比fopen/file_get_contents 好很多。
2)fopen/file_get_contents在請求HTTP時,使用的是http_fopen_wrapper,不會keeplive。而curl卻可以。這樣在多次請求多個鏈接時,curl效率會好一些。(設置header頭應該可以)
3)fopen/file_get_contents函數會受到php.ini文件中allow_url_open選項配置的影響。如果該配置關閉了,則該函數也就失效了。而curl不受該配置的影響。
4)curl可以模擬多種請求,例如:POST數據,表單提交等,用戶可以按照自己的需求來定制請求。而fopen/file_get_contents只能使用get方式獲取數據。
5)fopen/file_get_contents 不能正確下載二進制文件
6)fopen/file_get_contents 不能正確處理ssl請求
7)curl 可以利用多線程
8)使用 file_get_contents 的時候如果 網絡出現問題, 很容易堆積一些進程在這里
9)如果是要打一個持續連接,多次請求多個頁面。那么file_get_contents就會出問題。取得的內容也可能會不對。所以做一些類似采集工作的時候,肯定就有問題了。對做采集抓取的用curl,如果還有同不相信下面我們再做個測試
curl與file_get_contents性能對比PHP源代碼如下:
1829.php
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
<?php /** * 通過淘寶IP接口獲取IP地理位置 * @param string $ip * @return: string **/ function getCityCurl( $ip ) { $url = " http://ip.taobao.com/service/getIpInfo.php?ip= " . $ip ; $ch = curl_init(); $timeout = 5; curl_setopt ( $ch , CURLOPT_URL, $url ); curl_setopt ( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt ( $ch , CURLOPT_CONNECTTIMEOUT, $timeout ); $file_contents = curl_exec( $ch ); curl_close( $ch ); $ipinfo =json_decode( $file_contents ); if ( $ipinfo ->code== '1' ){ return false; } $city = $ipinfo ->data->region. $ipinfo ->data->city; return $city ; } function getCity( $ip ) { $url = " http://ip.taobao.com/service/getIpInfo.php?ip= " . $ip ; $ipinfo =json_decode( file_get_contents ( $url )); if ( $ipinfo ->code== '1' ){ return false; } $city = $ipinfo ->data->region. $ipinfo ->data->city; return $city ; } // for file_get_contents $startTime = explode ( ' ' ,microtime()); $startTime = $startTime [0] + $startTime [1]; for ( $i =1; $i <=10; $i ++) { echo getCity( "121.207.247.202" ). "</br>" ; } $endTime = explode ( ' ' ,microtime()); $endTime = $endTime [0] + $endTime [1]; $totalTime = $endTime - $startTime ; echo 'file_get_contents:' .number_format( $totalTime , 10, '.' , "" ). " seconds</br>" ; //for curl $startTime2 = explode ( ' ' ,microtime()); $startTime2 = $startTime2 [0] + $startTime2 [1]; for ( $i =1; $i <=10; $i ++) { echo getCityCurl( '121.207.247.202' ). "</br>" ; } $endTime2 = explode ( ' ' ,microtime()); $endTime2 = $endTime2 [0] + $endTime2 [1]; $totalTime2 = $endTime2 - $startTime2 ; echo "curl:" .number_format( $totalTime2 , 10, '.' , "" ). " seconds" ; ?> |
測試訪問
file_get_contents速度:4.2404510975 seconds
curl速度:2.8205530643 seconds
curl比file_get_contents速度快了30%左右,最重要的是服務器負載更低.
ps:php函數file_get_contents與curl效率及穩定性問題
習慣了使用方便快捷的file_get_contents函數抓取別家網站內容,但是總是會遇到獲取失敗的問題,盡管按照手冊中的例子設置了超時,可多數時候不好使:
$config['context'] = stream_context_create(array('http' => array('method' => "GET",'timeout' => 5)));
'timeout' => 5//這個超時時間不穩定,經常不好使。這時候,看一下服務器的連接池,會發現一堆類似下面的錯誤,讓你頭疼萬分:
file_get_contents(http://***): failed to open stream…
不得已,安裝了curl庫,寫了一個函數替換:
1
|
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function curl_get_contents( $url ) { $ch = curl_init(); curl_setopt( $ch , CURLOPT_URL, $url ); //設置訪問的url地址 //curl_setopt($ch,CURLOPT_HEADER,1); //是否顯示頭部信息 curl_setopt( $ch , CURLOPT_TIMEOUT, 5); //設置超時 curl_setopt( $ch , CURLOPT_USERAGENT, _USERAGENT_); //用戶訪問代理 User-Agent curl_setopt( $ch , CURLOPT_REFERER,_REFERER_); //設置 referer curl_setopt( $ch ,CURLOPT_FOLLOWLOCATION,1); //跟蹤301 curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); //返回結果 $r = curl_exec( $ch ); curl_close( $ch ); return $r ; } |
如此,除了真正的網絡問題外,沒再出現任何問題。
這是別人做過的關于curl和file_get_contents的測試:
file_get_contents抓取google.com需用秒數:
2.31319094
2.30374217
2.21512604
3.30553889
2.30124092
curl使用的時間:
0.68719101
0.64675593
0.64326
0.81983113
0.63956594
差距很大吧?呵呵,從我使用的經驗來說,這兩個工具不只是速度有差異,穩定性也相差很大。建議對網絡數據抓取穩定性要求比較高的朋友使用上面的 curl_file_get_contents函數,不但穩定速度快,還能假冒瀏覽器欺騙目標地址哦!