前言:由php的運行機制決定,其實php在運行階段我們也是可以進行緩存的從而提高程序運行效率,這就是我們常說的opcode緩存。
1、簡述php的運行機制
(因為本文是寫opcode緩存的所以這里只是簡要概述,后邊會專門寫一篇揭秘php運行機制的。)
a).php文件通過瀏覽器過來
b)請求交給SAPI,隨后SAPI層將控制權轉給PHP
c)zend_language_scanner對代碼進行掃描,對php代碼進行詞法分析轉換成一系列的tokens array
d)zend_language_parser將c步驟產生的一系列tokens處理掉空格等無用的代碼以后轉換成一系列表達式
e)經過compiler階段生成opcode返回zend_op_array指針
f)zend_vm_execute根據傳入的zend_op_array指針,執行opcode並將結果返回輸出
(下圖來自互聯網,但是描述的很不錯借花獻佛了)
2、opcode簡介
Opcode是operation code(操作碼)的簡稱,其實就是第一小節c)、d)、e)步驟產生的一種中間碼,
opcode是一個四元組,(opcode, op1, op2, result),它們分別代表操作碼,第一操作數,第二操作數,結果。
如:
<?php echo "taobao search blog"; ?>
對應的tokens
Array ( [0] => Array ( [0] => 367 [1] => <?php [2] => 1 ) [1] => Array ( [0] => 316 [1] => echo [2] => 1 ) [2] => Array ( [0] => 370 [1] => [2] => 1 ) [3] => Array ( [0] => 315 [1] => "taobao search blog" [2] => 1 ) [4] => ; [5] => Array ( [0] => 370 [1] => [2] => 1 ) [6] => Array ( [0] => 369 [1] => ?> [2] => 1 ) )
對應的opcode就是:
line # * op fetch ext return operands --------------------------------------------------------------------------------- 2 0 > ECHO 'taobao+search+blog' 4 1 > RETURN 1 2* > ZEND_HANDLE_EXCEPTION
3、使用apc對opcode緩存
a)假設php路徑為/home/ad/php
對opcode進行緩存的軟件很多(apc、eAcclerator、Xcache、Zend Platform),這里主要介紹apc
APC提供兩種緩存功能,即緩存Opcode(目標文件),我們稱之為apc_compiler_cache。同時它還提供一些接口用於PHP開發人員將用戶數據駐留在內存中,我們稱之為apc_user_cache。我們這里主要討論apc_compiler_cache的配置。
下載地址:http://pecl.php.net/package/APC
最新版本為APC-3.1.6.tgz
wget http://pecl.php.net/get/APC-3.1.6.tgz tar -zxvf APC-3.1.6.tgz cd APC-3.1.6 /home/ad/php/bin/phpize ./configure --enable-apc --enable-apc-mmap --with-php-config=/home/ad/php/bin/php-config make make install
編輯php.ini
添加apc的配置
[apc] extension=apc.so apc.enabled=1 apc.shm_segments = 1 apc.shm_size = 128 apc.ttl = 0 apc.user_ttl = 7200 apc.num_files_hint = 1000 apc.write_lock=1 apc.stat = 0 apc.max_file_size=1M apc.filters = a.php,b.php apc.cache_by_default=1
重新apache就ok啦
4、常用參數的解析
apc.enabled 開啟apc 設置為0關閉,1為開啟
apc.shm_segments 共享內存塊數
apc.shm_size 共享內存大小,但是是M
那么顯然共享內存的總數就是apc.shm_segments*apc.shm_size
apc.num_files_hint 允許多少個opcode被緩存
apc.stat 為1的時候會自動檢查opcode對應的php文件是否有更新,有更新的話會自動更新。設置為0的話就不會去檢查了這樣會提高apc的效率,但是要使php的修改生效的話就必須重啟apache了,或者使用函數apc_cache_clear()來清空緩存
apc.ttl opcode緩存的過期時間,設置為0表示不過期,如果不為0會檢查兩次請求之間的時間,如果時間大於設置值那么會更新opcode緩存
apc.write_lock 表示多個進程同時更新一份opcode緩存的時候那么只讓最先的一個生效,可以有效避免寫沖突
apc.max_file_size 超過設置值大小的文件不被緩存
apc.filters 需要特例的文件,多個文件用逗號(,)相隔
apc.filters 與 apc.cache_by_default結合使用,
當apc.cache_by_default為1時apc.filters文件不被緩存,當apc.cache_by_default為0時僅apc.filters文件被緩存
5:apc使用例子
案例一:使用PHP的APC模塊制作上傳進度條
https://www.ttlsa.com/php/php-apc-upload-process/
案例二:opcache安裝配置
http://blog.jjonline.cn/linux/135.html