curl的速度為什么比file_get_contents快以及具體原因
一、背景

大家做項目的時候,不免會看到前輩的代碼。博主最近看到前輩有的時候請求外部接口用的是file_get_contents,有的用的是curl。稍微了解這兩部分的同學都知道,curl在性能上和速度上是優于file_get_contents的,那么為什么呢,從哪里體現出來的差距呢?
二、file_get_contents和curl
1、file_get_contents概述
file_get_contents() 函數把整個文件讀入一個字符串中。
手冊:http://www.w3school.com.cn/php/func_filesystem_file_get_contents.asp
這里可以看出來,file_get_contents函數的最優選擇是讀取文件的內容。要求對方的服務器php.ini必須開啟:allow_url_fopen
2、curl的概述
CURL是一個非常強大的開源庫,支持很多協議,包括HTTP、FTP、TELNET等,我們使用它來發送HTTP請求。它給我 們帶來的好處是可以通過靈活的選項設置不同的HTTP協議參數,并且支持HTTPS。CURL可以根據URL前綴是“HTTP” 還是“HTTPS”自動選擇是否加密發送內容。需要php.ini開啟curl擴展
參考文章:http://www.cnblogs.com/manongxiaobing/p/4698990.html
從定義上來說,curl作為一個開源庫,擁有眾多的語法也支持眾多的協議,這點能看出來curl相比于file_get_contents() 是能做更多的事情的
三、為什么curl比file_get_contents好
博主百度了網上的眾多說法,總共分為下面幾個方面:
1、file_get_contents() 更容易造成服務器掛掉
關于造成服務器掛掉,這部分主要涉及兩個方面:
(1)直接使用file_get_contents,未設置超時處理造成nginx報錯:502 Bad Gateway
這部分大家可以參考博客:http://www.cnblogs.com/aipiaoborensheng/p/5000096.html
設置超時時間即可。當然,如果是選用curl的話,設置超時時間會更加的方便,明顯,一般不會因為超時而造成服務器垮掉。
(2)用file_get_contents請求效率很低,頁面經常卡頓很久
這部分在網上也有個解釋,說file_get_contents每次請求遠程URL中的數據都會重新做DNS查詢,并不對DNS信息進行緩存。而curl則可以通過設置參數的方式來緩存DNS,從而達到快速訪問的目的
curl設置DNS緩存:
CURLOPT_DNS_USE_GLOBAL_CACHE 啟用時會啟用一個全局的DNS緩存,此項為線程安全的,并且默認啟用。
CURLOPT_DNS_CACHE_TIMEOUT 設置在內存中保存DNS信息的時間,默認為120秒。
參考鏈接:https://www.cnblogs.com/jking10/p/6595981.html
(3)curl能做到file_get_contents做不到的事情
這部分是博主之前解決一個需求的時候發現的。當我需要把網絡圖片轉換為二進制的圖片流的時候,curl能實現,而file_get_contens就不行。
參考我之前的文章:https://blog.csdn.net/LJFPHP/article/details/81357839
2、file_get_contents速度很慢
關于速度慢的原因,一部分是DNS緩存,這確實是file_get_contents的瓶頸,另一方面就是關于header頭的原因。大家都知道,file_get_contents的請求是不帶頭的,這樣它接收完所有數據后,沒有主動斷開和服務器的http連接。
解決方案:
$opts = array(
'http'=>array(
'method' => 'POST',
'header' => 'Content-type:application/x-www-form-urlencoded',
'content' => $postdata,
'timeout' => 60 * 10 // 超時時間(單位:s)
'Connection'=>"close"
)
);
$context = stream_context_create($opts);
file_get_contents($filename, false, $context);
我們通過設置句柄的方式,定義超時時間和header頭,這樣就能最大化的提升file_get_contents的速度
3、file_get_contents請求HTTP時,使用的是http_fopen_wrapper,不會keeplive。而curl卻可以。這樣在多次請求多個鏈接時,curl效率會好一些。
這部分博主查詢了下keeplive的相關知識,發現自己對于http請求方面還不是很熟悉。關于keeplive也是一個很大模塊,博主這里就也不廢話了,給大家推薦幾篇不錯的博客,有興趣的可以看看:
(1)(apache)http的keeplive
https://blog.csdn.net/jackyrongvip/article/details/9217931
http://www.cnblogs.com/hixiaowei/p/9261358.html
(2)tcp的keepAlive
http://www.cnblogs.com/xiaoleiel/p/8308514.html
四、關于服務器是否支持file_get_contents的判斷方法
眾所周知的,file_get_contents是需要請求的服務商開啟allow_url_fopen,但是很多服務商為了安全考慮都會關掉這個功能。而curl是要求php必須開啟curl擴展。不過相對來說,很少有服務商不開啟curl的,所以curl的運用場合會更多一些。
這里我們可以使用php自帶的:function_exists方法來判斷服務商是否定義的有此方法。
文檔:http://php.net/manual/zh/function.function-exists.php
代碼:
if(function_exists('file_get_contents')) {
$file_contents = file_get_contents($url);
} else {
//這里可以執行curl方案
}
通過對比我們也能發現兩個函數的優劣勢。如果是讀取文件或者只是去拉取數據,那么file_get_contents的效率比較高 也比較簡單。如果是要進行遠程連接或者高頻次的訪問,那么還是老老實實用curl吧。
HTTP PHP
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。