使用php數(shù)據(jù)緩存技術(shù)提高執(zhí)行效率
為什么要使用php緩存技術(shù)?理由很簡單:提高效率。在程序開發(fā)中,獲取信息的方式主要是查詢數(shù)據(jù)庫,除此以外,也可能是通過Web Services或者別的某種方法,無論哪種方法,在大量的并發(fā)訪問面前,它們都可能成為效率的瓶頸,為了解決這些問題,人們提出了很多解決方案,其中一些是利用優(yōu)化軟件(如:APC,Eaccelerator,Zend Optimizer等等)來提高程序的運(yùn)行效率,合理的運(yùn)用這些軟件,往往能使程序的運(yùn)行效率得到數(shù)量級上的提升,但前提是你必須擁主機(jī)的控制權(quán),以便能夠安裝這些軟件,如果你使用的是虛擬主機(jī)的話,那么只能祈禱你的服務(wù)提供商已經(jīng)預(yù)裝了某個優(yōu)化軟件,否則就必須自己使用PHP來實(shí)現(xiàn)相應(yīng)的緩存功能。
PHP緩存技術(shù)是一種解釋型語言,屬于邊編譯邊運(yùn)行,包括PHP編譯緩存和PHP數(shù)據(jù)緩存兩種。PHP緩存,這種運(yùn)行模式的優(yōu)點(diǎn)是程序修改很方便,但是運(yùn)行效率卻很低下。PHP編譯緩存針對這種情況做改進(jìn)處理,使得PHP語言只要運(yùn)行一次,就可以把程序的編譯結(jié)果緩存起來。這樣,接下來的每次運(yùn)行都不需要再次編譯了,這大大提高PHP運(yùn)行速度。
PHP 緩存介紹
什么是緩存
數(shù)據(jù)交換的緩沖區(qū)(稱作Cache)
臨時文件交換區(qū)
緩存作用
減少網(wǎng)絡(luò)延遲,加快頁面打開速度
減少數(shù)據(jù)查詢次數(shù),降低數(shù)據(jù)庫壓力
降低系統(tǒng)負(fù)荷,極大的提升系統(tǒng)性能
常用緩存類型
文件緩存:使用 PHP 文件操作函數(shù),把數(shù)據(jù)緩存到服務(wù)器磁盤文件中
內(nèi)存緩存:Redis、Memcached、MongoDB
Opcode緩存:PHP 是一種解釋型腳本語言,在 PHP 執(zhí)行過程中,虛擬機(jī)會把 PHP 代碼翻譯成中間語言,這種中間語言就叫 Opcode,然后虛擬機(jī)再把 Opcode 順序執(zhí)行。把 PHP 代碼對應(yīng)的 Opcode緩存到內(nèi)存中,加速 PHP 執(zhí)行,減少了代碼翻譯成中間語言這一步操作。
| 文件緩存 | 內(nèi)存緩存 | Opcode緩存 | |
|---|---|---|---|
| 存儲介質(zhì) | 磁盤文件 | 內(nèi)存 | 內(nèi)存 |
| 不足 | IO操作慢、文件鎖的存在 | 占內(nèi)存、不持久 | 部署代碼刷新慢 |
| 應(yīng)用舉例 | 新聞數(shù)據(jù)、城市區(qū)域 | 會員、商品、Session | OpcodeCache(代碼加速) |
PHP 常用內(nèi)存緩存介紹
PHP是一種腳本語言,腳本執(zhí)行結(jié)束之后,所有的變量全部釋放掉,本身沒有能力將數(shù)據(jù)常駐內(nèi)存。
PHP借助于內(nèi)存服務(wù)器將緩存數(shù)據(jù)儲存在服務(wù)器內(nèi)存。
優(yōu)點(diǎn):讀寫速度快、跨服務(wù)器存儲(例如在做多服務(wù)器集群的時候,可以將 Session 存儲于內(nèi)存緩存服務(wù)器中)、易于解決主從同步問題,并發(fā)問題。
不足:占用了內(nèi)存空間、緩存數(shù)據(jù)有大小限制、數(shù)據(jù)不易持久化存儲。(但是內(nèi)存緩存帶給我們的方便足夠可以忽略他的不足)
常用內(nèi)存緩存:Memcached、Redis、MongoDB
| Memcached | Redis | MongoDB | |
|---|---|---|---|
| 儲存數(shù)據(jù)類型 | string | string, list, hash, set | bson 豐富查詢方式 |
| 數(shù)據(jù)儲存位置 | 內(nèi)存 | 內(nèi)存 + 硬盤 | 內(nèi)存 + 硬盤 |
| 持久化 | 最長30天 | RDB 文件快照,AOF(記錄寫操作)持久化 | journal持久化 |
| 使用場景 | Session 商品緩存(緩存 < 1MB) | 緩存、隊(duì)列 | 日志、區(qū)域信息、評論 |
php opcode緩存
PHP Opcode原理
Opcode是一種PHP腳本編譯后的中間語言,就像Java的ByteCode,或者.NET的MSL,舉個例子,比如你寫下了如下的PHP代碼
<?php echo "Hello World"; $a = 1 + 1; echo $a; ?>
PHP執(zhí)行這段代碼會經(jīng)過如下4個步驟(確切的來說,應(yīng)該是PHP的語言引擎Zend)
1.Scanning(Lexing) ,將PHP代碼轉(zhuǎn)換為語言片段(Tokens) 2.Parsing, 將Tokens轉(zhuǎn)換成簡單而有意義的表達(dá)式 3.Compilation, 將表達(dá)式編譯成Opocdes 4.Execution, 順次執(zhí)行Opcodes,每次一條,從而實(shí)現(xiàn)PHP腳本的功能。
學(xué)過編譯原理的同學(xué)都應(yīng)該對編譯原理中的詞法分析步驟有所了解,Lex就是一個詞法分析的依據(jù)表。 Zend/zend_language_scanner.c會根據(jù)Zend/zend_language_scanner.l(Lex文件),來輸入的 PHP代碼進(jìn)行詞法分析,從而得到一個一個的“詞”,PHP4.2開始提供了一個函數(shù)叫token_get_all,這個函數(shù)就可以講一段PHP代碼 Scanning成Tokens;如果用這個函數(shù)處理前面的PHP代碼,將會得到如下結(jié)果:
Array
(
[0] => Array
(
[0] => 367
[1] => Array
(
[0] => 316
[1] => echo
)
[2] => Array
(
[0] => 370
[1] =>
)
[3] => Array
(
[0] => 315
[1] => "Hello World"
)
[4] => ;
[5] => Array
(
[0] => 370
[1] =>
)
[6] => =
[7] => Array
(
[0] => 370
[1] =>
)
[8] => Array
(
[0] => 305
[1] => 1
)
[9] => Array
(
[0] => 370
[1] =>
)
[10] => +
[11] => Array
(
[0] => 370
[1] =>
)
[12] => Array
(
[0] => 305
[1] => 1
)
[13] => ;
[14] => Array
(
[0] => 370
[1] =>
)
[15] => Array
(
[0] => 316
[1] => echo
)
[16] => Array
(
[0] => 370
[1] =>
)
[17] => ;
)分析這個返回結(jié)果我們可以發(fā)現(xiàn),源碼中的字符串,字符,空格,都會原樣返回。每個源代碼中的字符,都會出現(xiàn)在相應(yīng)的順序處。而,其他的比如標(biāo)簽,操作符,語句,都會被轉(zhuǎn)換成一個包含倆部分的Array: Token ID (也就是在Zend內(nèi)部的改Token的對應(yīng)碼,比如,T_ECHO,T_STRING),和源碼中的原來的內(nèi)容。
接下來,就是Parsing階段了,Parsing首先會丟棄Tokens Array中的多于的空格,然后將剩余的Tokens轉(zhuǎn)換成一個一個的簡單的表達(dá)式
1.echo a constant string 2.add two numbers together 3.store the result of the prior expression to a variable 4.echo a variable
然后就改Compilation階段了,它會把Tokens編譯成一個個op_array, 每個op_arrayd包含如下5個部分:
1.Opcode數(shù)字的標(biāo)識,指明了每個op_array的操作類型,比如add , echo 2.結(jié)果 存放Opcode結(jié)果 3.操作數(shù)1 給Opcode的操作數(shù) 4.操作數(shù)2 5.擴(kuò)展值1個整形用來區(qū)別被重載的操作符
比如,我們的PHP代碼會被Parsing成:
* ZEND_ECHO 'Hello World' * ZEND_ADD ~0 1 1 * ZEND_ASSIGN !0 ~0 * ZEND_ECHO !0
php文件緩存
因?yàn)槿绻绦蛟L問數(shù)據(jù)庫時數(shù)據(jù)量較大,執(zhí)行起來會比較慢。而且每一次刷新頁面都會訪問依稀數(shù)據(jù)庫,然后再把數(shù)據(jù)顯示在頁面上。 設(shè)置緩存也有一個缺點(diǎn),那就是緩存時間要設(shè)置好,如果緩存時間較長,那么數(shù)據(jù)庫數(shù)據(jù)變化時,不能及時的在頁面上顯示。例如緩存不能用在秒殺商品,或者出售商品上面,因?yàn)閿?shù)量不能及時的更新。
<?php
//緩存文件一般都放在caches文件夾里面。
//定義一個該頁面的緩存文件路徑,也就是該緩存的文件放在哪個文件夾里面。
$filename = "../cache/testhuancun.html";//定義了一個緩存的文件,文件名為testhuancun.html,位置在../cache文件夾里面。
//設(shè)置一個緩存時間
$time = 10;//代表緩存時間設(shè)置為10s.
//判斷緩存文件是否存在
if(!file_exists($filename) || filemtime($filename)+$time<time())
//判斷文件是否存在,如果不存在,執(zhí)行{}里面的代碼。還要判斷緩存時間有沒有過,如果已經(jīng)過了,要重新讀取數(shù)據(jù)庫更新緩存。
//filemtime($filename)讀取文件最后被修改的時間,time()取當(dāng)前時間戳
{
//開啟內(nèi)存緩存
ob_start();//這里開啟內(nèi)存緩存以后,下面要輸出的內(nèi)容全部放在內(nèi)存緩存里面。
include("../init.inc.php");
include("../DBDA.php");
$db = new DBDA();
$sql = "select * from nation";
$attr = $db->Query($sql);
$smarty->assign("nation",$attr);
$smarty->display("test.html");
//把內(nèi)存里面的內(nèi)容讀出來
$nr = ob_get_contents();//ob就是代表的緩存,讀取的內(nèi)容就是整個靜態(tài)頁面。
//將讀到的內(nèi)容存放到緩存文件
file_put_contents($filename,$nr);//get是取出內(nèi)容,put是往里放內(nèi)容,把內(nèi)存緩存的文件存到¥filename里面。
//清除內(nèi)存緩存
ob_flush();//把內(nèi)存緩存的內(nèi)容清除掉,不讓它們繼續(xù)留在緩存內(nèi)存里面,但是需要緩存的內(nèi)容已經(jīng)放在了$filename里面了,已經(jīng)保存下來了。
echo "#############################";//輸出內(nèi)容加上一句話,觀察輸出內(nèi)容是輸出的緩存頁面還是加載數(shù)據(jù)庫的頁面。這句話放在了ob_flush后面,不會被清除掉。
}
else//如果緩存文件存在,直接將緩存文件拿到頁面顯示。
{
include($filename);//將緩存的頁面加載到顯示頁面中
}到此這篇關(guān)于使用php數(shù)據(jù)緩存技術(shù)提高執(zhí)行效率的文章就介紹到這了,更多相關(guān)php數(shù)據(jù)緩存技術(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何讓thinkphp在模型中自動完成session賦值小教程
在項(xiàng)目中遇到一個問題,需要讓thinkphp在模型中自動完成session賦值,經(jīng)過一番研究,終于實(shí)現(xiàn),下面記錄一下,另附上thinkPHP的session的相關(guān)知識2014-09-09
基于win2003虛擬機(jī)中apache服務(wù)器的訪問
下面小編就為大家?guī)硪黄趙in2003虛擬機(jī)中apache服務(wù)器的訪問。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
php魔術(shù)函數(shù)__call()用法實(shí)例分析
這篇文章主要介紹了php魔術(shù)函數(shù)__call()用法,實(shí)例分析了__call()函數(shù)的功能及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02
深入理解PHP之?dāng)?shù)組(遍歷順序) Laruence原創(chuàng)
經(jīng)常會有人問我, PHP的數(shù)組, 如果用foreach來訪問, 遍歷的順序是固定的么? 以什么順序遍歷呢?下面看Laruence整理的2012-06-06
PHP編程實(shí)現(xiàn)計(jì)算抽獎概率算法完整實(shí)例
這篇文章主要介紹了PHP編程實(shí)現(xiàn)計(jì)算抽獎概率算法,結(jié)合完整實(shí)例形式分析了php隨機(jī)數(shù)運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-08-08
PHP 實(shí)現(xiàn)explort() 功能的詳解
本篇文章是對PHP 實(shí)現(xiàn)explort()功能進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06

