摘要:原文地址實現遠程下載文件到服務端并不是什么新鮮玩意,用等都能夠輕易實現。原理也許你在搜索下載進度條的時候會看到有些文章使用的輸出控制函數之類的控制緩沖區來實現進度條。
原文地址:https://prinzeugen.net/implem...
PHP 實現遠程下載文件到服務端并不是什么新鮮玩意,用 cURL、file_get_contents、fopen 等都能夠輕易實現。
但是這幾種常規的方法都是在一個線程內下載文件,等文件下載完畢以后才能返回 HTTP 響應。所造成的結果就是用戶在頁面上點擊「下載到服務器」按鈕后,會看到空白頁和加載的小菊花轉啊轉,轉好久之后才出現「下載成功」的頁面。
當然,我上面所舉例的情況是只使用純粹的表單 POST 發送請求的情況。現在的話就算再不濟也一般會使用 ajax 發送請求,然后在前臺放個加載動畫,等收到下載成功的回應之后再進行下一步操作。
但是!即使是去掉了惡心的且需要等待的空白頁,這樣做還是對用戶體驗有不好的影響。沒有具體的下載進度,只有一個一直轉呀轉的菊花圖,估計挺多用戶都無法坐和放寬吧(至少對于我來說是這樣的)
而我一個 PHP 項目的一鍵更新系統正好需要重構,遂研究了如何在 PHP 作為后端時顯示遠程文件下載進度條,并搗鼓出了個像樣的解決方案,在這里分享一下。
也許你在搜索「PHP 下載 進度條」的時候會看到有些文章使用 PHP 的輸出控制函數(flush 之類的)控制緩沖區來實現進度條。但是——
那都是狗屁!
沒有人可以保證用戶的 PHP 關閉了默認開啟的 output buffering,也無法保證 瀏覽器 / Web Server 不對腳本輸出進行緩存。如果上述兩者其中之一處于開啟狀態的話,你就會喜聞樂見的發現本應該慢慢增長的進度條會在等待完漫長的 xx 秒后一下子蹦到 100%_(因為控制前端進度條長度的語句被緩存起來,在腳本執行結束后一并發送了,而不是一塊一塊地傳給瀏覽器)_。
關于上面緩沖區控制的進度條就是辣雞的更多討論可以查看文章底部的參考鏈接。
閑話休提。那么我們該如何實現下載進度條的更新呢?
首先通過后端一點點輸出控制進度條語句的方案已經 PASS 了,那么我們很自然的就會想到——
在前端設置一個定時器,Ajax 輪循下載進度并更新頁面上的進度條。
0x02 概述知道了原理之后,我們先來考慮下整體的架構與步驟。
用戶點擊「下載」按鈕,前端展示出進度條,并 ajax 發送 prepare-download 的請求;
后端收到請求,進行遠程下載的準備工作 —— 準備好遠程文件鏈接、臨時文件存放位置以及文件的大小,并返回給瀏覽器;
前端拿到文件大小等信息后,發送真正的 start-download 請求(這個請求耗時可能會很長),并啟動輪循的計時器;
計時器啟動后,每隔一段時間發送 get-file-size 請求,獲取當前臨時文件的大小,計算進度后更新進度條;
直到下載完成。
下面給出前后端代碼的實例。
0x03 后端代碼照例放在 Gist 上,加載不出自行解決:
https://gist.github.com/print...
示例代碼使用了 ?action=xxx 的 Query String 形式來區分不同的指令,這些請酌情修改。和我業務邏輯有關的一些關鍵函數都被我替換為淺顯易懂的名字(譬如 get_remote_file_url)了,需要你自己去替換實現。
0x04 前端https://gist.github.com/print...
0x05 效果 & 總結實例代碼用了 fopen 和循環 fwrite 寫入一個 chunk 的數據到臨時文件,這是借鑒了 KODExplorer 遠程下載的函數,在此致謝。另外也有通過 curl_setopt($ch, CURLOPT_FILE, $fp); 給 cURL 設置一個文件句柄的方法,但是我沒有測試成功,希望各位也能試一試。
以上。
參考鏈接PHP: flush - Manual 的「說明」部分
PHP progress bar - PHP Coding Help - PHP Freaks
What is output buffering? - Stack Overflow
KODExplorer/file.function.php at master
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/22087.html
摘要:配合實現上傳進度條配合實現上傳進度條,一直以為是無法做到進度條一個動態的功能,原來還是自己的知識面不夠,看到了擴展相關的一些文章,利用擴展達到了動態實現效果。根據找到相關的文章自己并在此基礎上做了一些小修改。 PHP配合apc實現上傳進度條PHP配合apc實現上傳進度條, 一直以為PHP是無法做到進度條一個動態的功能,原來還是自己的知識面不夠,看到了apc擴展相關的一些文章,利用apc...
摘要:自帶的上傳進度功能,需要擴展支持。于是想到利用的模塊來實現上傳進度。接下來使用模塊替代的文件上傳功能,目的是提高文件上傳的性能。而且可以避免上傳大文件時執行超時引起錯誤。新建一個對象,把設置成剛上傳的文件。 Drupal 8 自帶的上傳進度功能,需要PECL uploadprogress library擴展支持。安裝后發現效果還是不太好,不知道什么原因,進度條不能正常顯示,而且上傳較大...
摘要:自帶的上傳進度功能,需要擴展支持。于是想到利用的模塊來實現上傳進度。接下來使用模塊替代的文件上傳功能,目的是提高文件上傳的性能。而且可以避免上傳大文件時執行超時引起錯誤。新建一個對象,把設置成剛上傳的文件。 Drupal 8 自帶的上傳進度功能,需要PECL uploadprogress library擴展支持。安裝后發現效果還是不太好,不知道什么原因,進度條不能正常顯示,而且上傳較大...
摘要:我們在使用異步事件處理時還能順便獲得一項優勢,那就是能夠監控文件的讀取進度這對于讀取大文件查找錯誤和預測讀取完成時間非常實用。和事件可用于監控讀取進度。以下示例演示了如何通過顯示進度條來監控讀取狀態。 我們在使用異步事件處理時還能順便獲得一項優勢,那就是能夠監控文件的讀取進度;這對于讀取大文件、查找錯誤和預測讀取完成時間非常實用。 onloadstart 和 onprogress 事件...
閱讀 1702·2021-11-18 10:02
閱讀 2218·2021-11-15 11:38
閱讀 2666·2019-08-30 15:52
閱讀 2190·2019-08-29 14:04
閱讀 3231·2019-08-29 12:29
閱讀 2086·2019-08-26 11:44
閱讀 994·2019-08-26 10:28
閱讀 830·2019-08-23 18:37