關於Nginx安裝PHP的fileinfo和xsendfile模組的一些事宜
Fileinfo作用:本模組中的函式通過在檔案的給定位置查詢特定的 魔術 位元組序列 來猜測檔案的內容型別以及編碼(通俗來講就是獲取檔案的MIME資訊)也可以幫助系統顯示圖片。
根據手冊的介紹fileinfo擴充套件從php5.3之後預設是開啟的,所以不需要我們單獨安裝。但是有的整合環境為了編譯php的時候提高速度或者節省資源就去掉了這個擴充套件的安裝。所以就需要我們自己動手來安裝了。
首先檢查系統是否已經安裝 或者直接執行 find / -name fileinfo
- [[email protected] ~]# php -i|grep fileinfo
- Configure Command => './configure' '--prefix=/alidata/server/php' '--enable-opcache' '--with-config-file-path=/alidata/server/php/etc' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--enable-fpm' '--enable-fastcgi' '--enable-static' '--enable-inline-optimization' '--enable-sockets' '--enable-wddx' '--enable-zip' '--enable-calendar' '--enable-bcmath' '--enable-soap' '--with-zlib' '--with-iconv' '--with-gd' '--with-xmlrpc' '--enable-mbstring' '--without-sqlite' '--with-curl' '--enable-ftp' '--with-mcrypt' '--with-freetype-dir=/usr/local/freetype.2.1.10' '--with-jpeg-dir=/usr/local/jpeg.6' '--with-png-dir=/usr/local/libpng.1.2.50' '--disable-ipv6' '--disable-debug' '--with-openssl' '--disable-maintainer-zts' '--disable-safe-mode' '--disable-fileinfo'
- fileinfo
- fileinfo support => enabled
如果出現上面說明已經安裝
php原始碼包下載地址:http://cn2.php.net
tar -zxvf php-7.1.0.tar.gz
cd php-7.1.0/ext/fileinfo
當前目錄執行 /usr/local/php/bin/phpize
如果執行成功,會有類似下面的資訊 Configuring for: PHP Api Version: 20151012 Zend Module Api No: 20151012 Zend Extension Api No: 320151012
執行configure配置
./configure --with-php-config=/usr/local/php/bin/php-config --enable-fileinfo
如果提示php-config命令不存在 configure: error: Cannot find php-config. Please use --with-php-config=PATH
可以執行yum install php-devel, 安裝php-devel,安裝完成之後再執行這條命令即可。
編譯安裝
make && make install
如果安裝成功,會有類似下面的資訊
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/
修改php.ini配置項
echo 'extension="fileinfo.so"' >> /usr/local/php/etc/php.ini
重啟php服務
service php-fpm restart
php -i | grep fileinfo
......
fileinfo
fileinfo support => enabled
在nginx中x-sendfile解決方案
很多時候使用者需要從網站下載檔案,如果檔案是可以通過一個固定連結公開獲取的,那麼我們只需將檔案存放到 webroot下的目錄裡就好。但大多數情況下,我們需要做許可權控制,例如下載 PDF 賬單,又例如下載網盤裡的檔案。這時,我們通常藉助於指令碼程式碼來實現,而這無疑會增加伺服器的負擔。
例如下面的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
一、這樣做有什麼問題?
這樣做意味著我們的程式需要將檔案內容從磁碟經過一個固定的 buffer 去迴圈讀取到記憶體,再發送給前端 web 伺服器,最後才到達使用者。當需要下載的檔案很大的時候,這種方式將消耗大量記憶體,甚至引發 php 程序超時或崩潰。Cache 也很頭疼,更不用說中斷重連的情況了。 一個理想的解決方式應該是,由 php 程式進行許可權檢查等邏輯判斷,一切通過後,讓前臺的 web 伺服器直接將檔案傳送給使用者——像 Nginx 這樣的前臺更善於處理靜態檔案。這樣一來 php 指令碼就不會被 I/O 阻塞了。
二、什麼是 X-Sendfile?
X-Sendfile 是一種將檔案下載請求由後端應用轉交給前端 web 伺服器處理的機制,它可以消除後端程式既要讀檔案又要處理髮送的壓力,從而顯著提高伺服器效率,特別是處理大檔案下載的情形下。
X-Sendfile 通過一個特定的 HTTP header 來實現:在 X-Sendfile 頭中指定一個檔案的地址來通告前端 web 伺服器。當 web 伺服器檢測到後端傳送的這個 header 後,它將忽略後端的其他輸出,而使用自身的元件(包括 快取頭 和 斷點重連 等優化)機制將檔案傳送給使用者。
不過,在使用 X-Sendfile 之前,我們必須明白這並不是一個標準特性,在預設情況下它是被大多數 web 伺服器禁用的。而不同的 web 伺服器的實現也不一樣,包括規定了不同的 X-Sendfile 頭格式。如果配置失當,使用者可能下載到 0 位元組的檔案。
使用 X-Sendfile 將允許下載非 web 目錄中的檔案(例如/root/),即使檔案在 .htaccess 保護下禁止訪問,也會被下載。
不同的 web 伺服器實現了不同的 HTTP 頭
SENDFILE 頭 | 使用的 WEB 器 |
---|---|
X-Sendfile | Apache, Lighttpd v1.5, Cherokee |
X-LIGHTTPD-send-file | Lighttpd v1.4 |
X-Accel-Redirect | Nginx, Cherokee |
使用 X-SendFile 的缺點是你失去了對檔案傳輸機制的控制。例如如果你希望在完成檔案下載後執行某些操作,比如只允許使用者下載檔案一次,這個 X-Sendfile 是沒法做到的,因為後臺的 php 指令碼並不知道下載是否成功。
三、怎樣使用?
Apache 請參考mod_xsendfile模組。下面我介紹 Nginx 的用法。
Nginx 預設支援該特性,不需要載入額外的模組。只是實現有些不同,需要傳送的 HTTP 頭為 X-Accel-Redirect。另外,需要在配置檔案中做以下設定
1 2 3 4 |
|
internal表示這個路徑只能在 Nginx 內部訪問,不能用瀏覽器直接訪問防止未授權的下載。
於是 PHP 傳送 X-Accel-Redirect 給 Nginx:
1 2 3 4 5 6 7 |
|
這樣使用者就會下載到 /some/path/protected/iso.img 這個路徑下的檔案。 如果你想傳送的是 /some/path/iso.img 檔案,那麼 Nginx 配置應該是
1 2 3 4 |
|