PHP下載網路資原始檔,有哪些好的解決方案?程式設計師小助手2020-07-14 21:32:48

引言

在程式內下載資原始檔,這本身就是一個充滿了不確定因素的事情。可能會因為網路超時連線中斷,或者程式故障丟擲各種異常,在實際中我們一般要避免在程式流程中下載檔案。

PHP下載網路資原始檔,有哪些好的解決方案?

如果是實在無法避免,用什麼辦法比較高效呢?或者說比較輕量級呢?本文就來說一說。

學習時間

最直接的辦法就是使用內建函式 file_get_contents。引數形式如下:

int file_put_contents( string $filename, mixed $data[, int $flags = 0[, resource $context]] )

這個函式設計的很巧妙,相容了很多場景下的使用。我們只需要按照相應的引數填入,就可以組裝出各種各樣的功能。

如果是下載資源,那麼會分為兩步。第一,把遠端資源拿到本地。第二,把該資源寫入本地檔案。使用程式碼實現如下:

file_put_contents(“Tmpfile。zip”, fopen(“http://someurl/file。zip”, ‘r’));

其中在位置引數 $data 的位置,傳入了一個fopen生成的檔案控制代碼。

根據函式手冊上所說,如果$data 指定的是流,則該流的緩衝區將被複制到指定的檔案。對標的函式是 stream_copy_to_stream。那樣寫起來就得是這樣的:

PHP下載網路資原始檔,有哪些好的解決方案?

是不是沒有file_put_contents精簡。難怪很多敲程式碼的老司機,習慣於使用這一個函式進行網路請求呢!

檔案操作

純粹使用檔案操作,也沒有問題,使用PHP提供的 fopen fclose fwrite fread 等函式,完全可以勝任。我們將其封裝為一個助手函式:

PHP下載網路資原始檔,有哪些好的解決方案?

因為不能確定原始檔案的長度,在讀寫的時候,需要注意快取區的大小,分塊讀入和寫入。其中引數 1024 * 8,指定每次讀寫 8K 位元組。使用 feof 判斷檔案是否到尾部。

網路請求

既然是網路資原始檔,使用上面的函式,無非都要發起 HTTP 請求。既然是網路請求,何不把這個功能交給 cURL 呢?這樣對於請求頭,請求體,響應體等等全程 HTTP 環節,都可以在程式內操作,容錯性肯定不差。

下面我們使用 cURL 庫進行檔案請求操作:

PHP下載網路資原始檔,有哪些好的解決方案?

如果是小小的資原始檔,下載起來不費時間,也不會阻礙接下來的流程。如果是超大檔案,費時間,而且還可能中斷,有沒有斷點續傳?有沒有自動壓縮?這都是問題。

所以,使用網路請求下載大檔案,這已經超出了 PHP 內建函式的範疇。我們需要功能更為強大的下載器,多資源,多執行緒,斷線續傳,自動重試。

寫在最後

本文透過3中方法對比了實現小檔案下載的功能,各有優劣,根據不同的場景需要開發者做出適當的選擇。

Happy coding :_)

我是 @程式設計師小助手 ,持續分享程式設計知識,歡迎關注。