1、概述
位元組碼 緩衝 不是 PHP 的新特性,有很多獨立的擴充可以實現,比如APC、eAccelerator和Xache等,但是截至目前這些擴充都沒有整合到PHP核心,從PHP 5.5.0開始,PHP內建了位元組程式碼快取功能,名為Zend Opcache 。
開始之前,我們先來看看什麼是位元組程式碼快取,以及位元組程式碼快取的作用是什麼。
眾所周知,PHP是解釋型語言,構建在Zend 虛擬機器之上,PHP解譯器在執行PHP指令碼時會解析PHP指令碼代碼,把PHP代碼編譯成一系列Zend作業碼(opcode: http://php.net/manual/zh/internals2.opcodes.php ,由於每個作業碼都是一個位元組長,所以又叫位元組碼,位元組碼可以直接被Zend虛擬機器執行),然後執行位元組碼。每次請求PHP檔案都是這樣,這會消耗很多資源,如果每次HTTP請求都必須不斷解析、編譯和執行PHP指令碼,消耗的資源更多。如果PHP源碼不變,相應的位元組碼也不會變化,顯然沒有必要每次都重建Opcode,結合在Web應用中無處不在的緩衝機制,我們可以把首次產生的Opcode緩衝起來,這樣下次直接從緩衝取,豈不是很快?下面是啟用Opcode緩衝之前和之後的流程圖:
位元組程式碼快取能儲存預先編譯好的PHP位元組碼,這樣,下次請求PHP指令碼時,PHP解譯器不用每次讀取、解析和編譯PHP代碼,直接從記憶體中讀取預先編譯好的位元組碼,然後立即執行,這樣能省很多時間,極大提升應用的效能。
2、啟用Zend Opcache
註:如果使用Windows開發環境,或者使用 brew 或 apt-get 等命令安裝的PHP可以略過編譯步驟。
預設情況下,Zend Opcache沒有開啟,需要我們在編譯時間使用 --enable-opcache 指定啟用Zend Opcache。
編譯好PHP後還需要在 php.ini 中指定Opcache擴充路徑:
zend_extension=/path/to/opcache.so
一般而言PHP編譯成功後會顯示Zend Opcache擴充路徑,但如果想不起來,可以使用如下命令找到PHP擴充所在目錄:
php-config --extension-dir
註:如果你使用Xdebug,需要在 php.ini 中先載入Zend Opcache,再載入Xdebug。
更新 php.ini 後重啟PHP進程並查看是否啟用成功:
3、配置Zend Opcache
啟用Zend Opcache後還需要在 php.ini 中配置Zend Opcache,下面是一份配置樣本作為參考:
opcache.validate_timestamps=1 //生產環境中配置為0opcache.revalidate_freq=0 //檢查指令碼時間戳記是否有更新時間opcache.memory_consumption=64 //Opcache的共用記憶體大小,以M為單位opcache.interned_strings_buffer=16 //用來儲存臨時字串的記憶體大小,以M為單位opcache.max_accelerated_files=4000 //Opcache雜湊表可以儲存的指令檔數量上限opcache.fast_shutdown=1 //使用快速停止續發事件
註:後續我們還會進一步介紹Zend Opcache的配置,PHP官網中列出了Zend Opcache的全部設定: http://ua2.php.net/manual/zh/opcache.configuration.php 。
4、使用Zend Opcache
Zend Opcache使用起來很簡單,因為啟用之後它會自動運行,Zend Opcache會自動在記憶體中緩衝預先編譯好的PHP位元組碼,如果緩衝了某個檔案的位元組碼,就執行對應的位元組碼。
如果 php.ini 中配置了 opcache.validate_timestamps 值為0,需要小心,因為Zend Opcache將不能覺察PHP指令碼的變化,必須手動清空Zend OPcache緩衝的位元組碼,才能讓它發現PHP檔案的變動。這個配置適合在生產環境中設定為0,但在開發環境會帶來不便,我們可以在開發環境中這樣配置啟用自動驗證緩衝功能:
opcache.validate_timestamps=1opcache.revalidate_freq=0