1. 程式人生 > >curl的速度為什麼比file_get_contents快以及具體原因

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吧。

end