php遠(yuǎn)程獲取文件內(nèi)容函數(shù)比較和區(qū)別(file_get_contents/curl/readfile/fopen):
1.fopen /file_get_contents 每次請(qǐng)求都會(huì)重新做DNS查詢,并不對(duì) DNS信息進(jìn)行緩存。但是CURL會(huì)自動(dòng)對(duì)DNS信息進(jìn)行緩存。對(duì)同一域名下的網(wǎng)頁或者圖片的請(qǐng)求只需要一次DNS查詢。這大大減少了DNS查詢的次數(shù)。所以
CURL的性能比fopen /file_get_contents 好很多。
2.fopen /file_get_contents 在請(qǐng)求HTTP時(shí),使用的是http_fopen_wrapper,不會(huì)keeplive。而curl卻可以。這樣在多次請(qǐng)求多個(gè)鏈接時(shí),curl效率會(huì)好一些。
3.fopen / file_get_contents 函數(shù)會(huì)受到php.ini文件中allow_url_open選項(xiàng)配置的影響。如果該配置關(guān)閉了,則該函數(shù)也就失效了。而curl不受該配置的影響。
4.curl 可以模擬多種請(qǐng)求,例如:POST數(shù)據(jù),表單提交等,用戶可以按照自己的需求來定制請(qǐng)求。而fopen / file_get_contents只能使用get方式獲取數(shù)據(jù)。
file_get_contents 獲取遠(yuǎn)程文件時(shí)會(huì)把結(jié)果都存在一個(gè)字符串中 fiels函數(shù)則會(huì)儲(chǔ)存成數(shù)組形式
因此,我還是比較傾向于使用curl來訪問遠(yuǎn)程url。Php有curl模塊擴(kuò)展,功能很是強(qiáng)大。
最近需要獲取別人網(wǎng)站上的音樂數(shù)據(jù)。用了file_get_contents函數(shù),但是總是會(huì)遇到獲取失敗的問題,盡管按照手冊(cè)中的 例子設(shè)置了超時(shí),可多數(shù)時(shí)候不會(huì)奏效:
代碼如下:
$config['context'] = stream_context_create(array('http' => array('method' => "GET",
'timeout' => 5//這個(gè)超時(shí)時(shí)間不穩(wěn)定,經(jīng)常不奏效
)
));
這時(shí)候,看一下服務(wù)器的連接池,會(huì)發(fā)現(xiàn)一堆類似的錯(cuò)誤,讓我頭疼萬分:
file_get_contents(http://***): failed to open stream…
現(xiàn)在改用了curl庫,寫了一個(gè)函數(shù)替換:
代碼如下:
function curl_file_get_contents($durl){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $durl);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
curl_setopt($ch, CURLOPT_REFERER,_REFERER_);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$r = curl_exec($ch);
curl_close($ch);
return $r;
}
如此,除了真正的網(wǎng)絡(luò)問題外,沒再出現(xiàn)任何問題。
這是別人做過的關(guān)于curl和file_get_contents的測試:
file_get_contents抓取google.com需用秒數(shù):
2.31319094
2.30374217
2.21512604
3.30553889
2.30124092
curl使用的時(shí)間:
0.68719101
0.64675593
0.64326
0.81983113
0.63956594
差距很大?呵呵,從我使用的經(jīng)驗(yàn)來說,這兩個(gè)工具不只是速度有差異,穩(wěn)定性也相差很大。
curl多用于互聯(lián)網(wǎng)網(wǎng)頁之間的抓取,fopen多用于讀取文件,而file_get_contents多用于獲取靜態(tài)頁面的內(nèi)容。
readfile() 優(yōu)勢是能夠一次性讀取大文件;不需要PHP預(yù)讀到內(nèi)存,下載速度更快,直接把文件的處理交由服務(wù)器。缺點(diǎn)就是不能控制負(fù)載。所以它是沒有內(nèi)存限制的,如果遇到報(bào)內(nèi)存錯(cuò)誤,先調(diào)用 ob_end_flush()之類的函數(shù)關(guān)閉緩沖區(qū)。
file_get_contents 也是沒 readfile()快, 因?yàn)橐彩亲吡藀hp的內(nèi)存。但是在讀取小文本內(nèi)容到字符串變量時(shí),這個(gè)函數(shù)最適合使用,簡單,更快。
fopen () 是一次讀取文件中的一行了,再需要逐行處理文件的時(shí)候,使用這個(gè)