1.概述
字節(jié)碼緩存不是PHP的新特性,有很多獨(dú)立的擴(kuò)展可以實(shí)現(xiàn),比如APC、eAccelerator和Xache等,但是截至目前這些擴(kuò)展都沒有集成到PHP內(nèi)核,從PHP 5.5.0開始,PHP內(nèi)置了字節(jié)碼緩存功能,名為Zend Opcache。
什么是字節(jié)碼緩存?作用是什么?
眾所周知,PHP是解釋型語(yǔ)言,構(gòu)建在Zend 虛擬機(jī)之上,PHP解釋器在執(zhí)行PHP腳本時(shí)會(huì)解析PHP腳本代碼,把PHP代碼編譯成一系列Zend操作碼(opcode:http://php.net/manual/zh/internals2.opcodes.php,由于每個(gè)操作碼都是一個(gè)字節(jié)長(zhǎng),所以又叫字節(jié)碼,字節(jié)碼可以直接被Zend虛擬機(jī)執(zhí)行),然后執(zhí)行字節(jié)碼。每次請(qǐng)求PHP文件都是這樣,這會(huì)消耗很多資源,如果每次HTTP請(qǐng)求都必須不斷解析、編譯和執(zhí)行PHP腳本,消耗的資源更多。如果PHP源碼不變,相應(yīng)的字節(jié)碼也不會(huì)變化,顯然沒有必要每次都重新生成Opcode,結(jié)合在Web應(yīng)用中無處不在的緩存機(jī)制,我們可以把首次生成的Opcode緩存起來,這樣下次直接從緩存取,豈不是很快?下面是啟用Opcode緩存之前和之后的流程圖:


2.啟用Opcache
默認(rèn)情況下,Zend Opcache沒有開啟,需要我們?cè)诰幾g時(shí)使用--enable-opcache指定啟用Zend Opcache。
編譯好PHP后還需要在php.ini中指定Opcache擴(kuò)展路徑:
zend_extension=/path/to/opcache.so
一般而言PHP編譯成功后會(huì)顯示Zend Opcache擴(kuò)展路徑,但如果想不起來,可以使用如下命令找到PHP擴(kuò)展所在目錄:
php-config --extension-dir
更新php.ini后重啟PHP進(jìn)程并查看是否啟用成功:

3、配置Zend Opcache
啟用Zend Opcache后還需要在php.ini中配置Zend Opcache,下面是一份配置示例作為參考:
opcache.revalidate_freq=0 //檢查腳本時(shí)間戳是否有更新時(shí)間
opcache.memory_consumption=64 //Opcache的共享內(nèi)存大小,以M為單位
opcache.interned_strings_buffer=16 //用來存儲(chǔ)臨時(shí)字符串的內(nèi)存大小,以M為單位
opcache.max_accelerated_files=4000 //Opcache哈希表可以存儲(chǔ)的腳本文件數(shù)量上限
opcache.fast_shutdown=1 //使用快速停止續(xù)發(fā)事件 ```
#4、使用Zend Opcache
Zend Opcache使用起來很簡(jiǎn)單,因?yàn)閱⒂弥笏鼤?huì)自動(dòng)運(yùn)行,Zend Opcache會(huì)自動(dòng)在內(nèi)存中緩存預(yù)先編譯好的PHP字節(jié)碼,如果緩存了某個(gè)文件的字節(jié)碼,就執(zhí)行對(duì)應(yīng)的字節(jié)碼。
如果php.ini中配置了opcache.validate_timestamps值為0,需要小心,因?yàn)閆end Opcache將不能覺察PHP腳本的變化,必須手動(dòng)清空Z(yǔ)end OPcache緩存的字節(jié)碼,才能讓它發(fā)現(xiàn)PHP文件的變動(dòng)。這個(gè)配置適合在生產(chǎn)環(huán)境中設(shè)置為0,但在開發(fā)環(huán)境會(huì)帶來不便,我們可以在開發(fā)環(huán)境中這樣配置啟用自動(dòng)驗(yàn)證緩存功能:
`opcache.validate_timestamps=1
opcache.revalidate_freq=0`