綜述
文件下載一直是PHP的痛腾节,傳統(tǒng)的做法是 PHP 讀取文件后建瘫,通過輸出到緩沖區(qū)到用戶瀏覽器崭捍,這里的弊端顯而易見尸折。
首先,PHP-FPM 是堵塞工作的,如果文件比較大孙乖,需要耗費一個 PHP 線程處理;
其次粒梦,使用 PHP 處理文件下載,非常浪費寶貴的內(nèi)存空間荸实。
理想的情況下匀们,我們可以采用 云存儲 和 CDN 去解決這個問題,但是對于需要驗證用戶信息的私有文件來說准给,這里就不適用了泄朴。
下面介紹四種方法去解決這個問題
私有文件解決方法:
1、X-Accel:
PHP:
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename="protected.pdf"');
header("X-Accel-Redirect: /protected/protected.pdf");
Nginx:
location /protected/{
internal; # 禁止外部訪問
root /files/protected;
}
internal 指令指定某個location只能被“內(nèi)部的”請求調(diào)用露氮,外部的調(diào)用請求會返回”Not found” (404)
“內(nèi)部的”是指下列類型:
? 指令error_page重定向的請求祖灰。
? ngx_http_ssi_module模塊中使用include virtual指令創(chuàng)建的某些子請求。
? ngx_http_rewrite_module模塊中使用rewrite指令修改的請求畔规。
引用:
https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/
https://segmentfault.com/q/1010000002981993
2局扶、Swoole:
上面的方法不是最完美的,因為需要啟動一個 PHP 進程來生成 Header叁扫,所以三妈,用 swoole 專門處理文件下載這一塊,用戶驗證莫绣、下載刪除 也很容易做畴蒲。
3、Nginx-Lua-Redis(大霧):
如果我們不適用 PHP对室,也是有方法的饿凛,下載的連接包含用戶的授權(quán)token,lua 拿到用戶 cookie 的 id 后软驰,查詢 reids 的 hash涧窒,如果存在token,就放下載锭亏,否則返回404.
引用:http://nginx.org/en/docs/http/ngx_http_core_module.html#aio