詳細講解PHP中緩存技術的應用

来源:http://www.cnblogs.com/aspnetjia/archive/2016/01/31/5173126.html
-Advertisement-
Play Games

PHP,一門最近幾年興起的web設計腳本語言,由於它的強大和可伸縮性,近幾年來得到長足的發展,php相比傳統的asp網站,在速度上有絕對的優勢,想mssql轉6萬條數據php如需要40秒,asp不下2分鐘.但是,由於網站的數據越來越多,我們渴求能更快速的調用數據,不必要每次都從資料庫掉,我們可以從其


PHP,一門最近幾年興起的web設計腳本語言,由於它的強大和可伸縮性,近幾年來得到長足的發展,php相比傳統的asp網站,在速度上有絕對的優勢,想mssql轉6萬條數據php如需要40秒,asp不下2分鐘.但是,由於網站的數據越來越多,我們渴求能更快速的調用數據,不必要每次都從資料庫掉,我們可以從其他的地方,比方一個文件,或者某個記憶體地址,這就是php的緩存技術,也就是Cache技術.

一般來說,緩存的目的是把數據放在一個地方讓訪問的更快點,毫無疑問,記憶體是最快的,但是,幾百M的數據能往記憶體放麽?這不現實,當然,有的時候臨時放如伺服器緩存,如ob_start()這個緩存頁面開啟的話在發送文件頭之前頁面內容都被緩存在記憶體中,知道等頁面輸出自動清楚或者等待ob_get_contents的返回,[或者被ob_end_clean顯示的清除,這在靜態頁面的生成中能很好的利用,在模板中能得到很好的體現,我的這篇文章深入的討論了:

談PHP生成靜態頁面,這是一種方式,但這是臨時性的,不是解決我們問題的好方法.

另外,在asp中有一對象application,可以保存公用的參數,這也算點緩存,但在php,我至今沒看到開發者產出這種對象,的確,沒必要.asp.net的頁面緩存技術就用的是viewstate,而cache就是文件關聯,(不一定准確),文件被修改,更新緩存,文件沒被修改而且不超時(註釋1),就讀取緩存,返回結果,就是這個思路,看看這個源碼:

<?php
classcache{
/*
ClassName:cache
Description:controltocachedata,$cache_out_timeisaarraytosavecachedatetimeout.
Version:1.0
Author:老農cjjer
Lastmodify:2006-2-26
AuthorURL:http://www.cjjer.com
*/
private$cache_dir;
private$expireTime=180;//緩存的時間是60秒
function__construct($cache_dirname){
if(!@is_dir($cache_dirname)){
if(!@mkdir($cache_dirname,0777)){
$this->warn(''緩存文件不存在而且不能創建,需要手動創建.'');
returnfalse;
}
}
$this->cache_dir=$cache_dirname;
}
function__destruct(){
echo''Cacheclassbye.'';
}
functionget_url(){
if(!isset($_SERVER[''REQUEST_URI''])){
$url=$_SERVER[''REQUEST_URI''];
}else{
$url=$_SERVER[''SCRIPT_NAME''];
$url.=(!empty($_SERVER[''QUERY_STRING'']))?''?''.$_SERVER[''QUERY_STRING'']:'''';
}
return$url;
}
functionwarn($errorstring){
echo"<b><fontcolor=''red''>發生錯誤:<pre>".$errorstring."</pre></font></b>";
}
functioncache_page($pageurl,$pagedata){
if(!$fso=fopen($pageurl,''w'')){
$this->warns(''無法打開緩存文件.'');//trigger_error
returnfalse;
}
if(!flock($fso,LOCK_EX)){//LOCK_NB,排它型鎖定
$this->warns(''無法鎖定緩存文件.'');//trigger_error
returnfalse;
}
if(!fwrite($fso,$pagedata)){//寫入位元組流,serialize寫入其他格式
$this->warns(''無法寫入緩存文件.'');//trigger_error
returnfalse;
}
flock($fso,LOCK_UN);//釋放鎖定
fclose($fso);
returntrue;
}
functiondisplay_cache($cacheFile){
if(!file_exists($cacheFile)){
$this->warn(''無法讀取緩存文件.'');//trigger_error
returnfalse;
}
echo''讀取緩存文件:''.$cacheFile;
//returnunserialize(file_get_contents($cacheFile));
$fso=fopen($cacheFile,''r'');
$data=fread($fso,filesize($cacheFile));
fclose($fso);
return$data;
}
functionreadData($cacheFile=''default_cache.txt''){
$cacheFile=$this->cache_dir."/".$cacheFile;
if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime)){
$data=$this->display_cache($cacheFile);
}else{
$data="fromherewocangetitfrommysqldatabase,updatetimeis<b>".date(''ldSofFYh:i:sA'')."</b>,過期時間是:".date(''ldSofFYh:i:sA'',time()+$this->expireTime)."----------";
$this->cache_page($cacheFile,$data);
}
return$data;
}

}
?>

 

 

下麵我打斷這個代碼逐行解釋.

三:程式透析

這個緩存類(類沒什麼好怕的.請繼續看)名稱是cache,有2個屬性:

private$cache_dir;
private$expireTime=180;

$cache_dir是緩存文件所放的相對網站目錄的父目錄,$expireTime(註釋一)是我們緩存的數據過期的時間,主要是這個思路:

當數據或者文件被載入的時候,先判斷緩存文件存在不,返回false,文件最後修改時間和緩存的時間和比當前時間大不,大的話說明緩存還沒到期,小的話返回false,當返回false的時候,讀取原始數據,寫入緩存文件中,返回數據.,

接著看程式:

function__construct($cache_dirname){
if(!@is_dir($cache_dirname)){
if(!@mkdir($cache_dirname,0777)){
$this->warn(''緩存文件不存在而且不能創建,需要手動創建.'');
returnfalse;
}
}
$this->cache_dir=$cache_dirname;
}

當類第一次被實例的時候構造預設函數帶參數緩存文件名稱,如文件不存在,創建一個有編輯許可權的文件夾,創建失敗的時候拋出異常.然後把cache類的$cache_dir屬性設置為這個文件夾名稱,我們的所有緩存文件都是在這個文件夾下麵的.

function__destruct(){
echo''Cacheclassbye.'';
}

這是class類的析構函數,為了演示,我們輸出一個字元串表示我們釋放cache類資源成功.

functionwarn($errorstring){
echo"<b><fontcolor=''red''>發生錯誤:<pre>".$errorstring."</pre></font></b>";
}

 

 

這個方法輸出錯誤信息.

functionget_url(){
if(!isset($_SERVER[''REQUEST_URI''])){
$url=$_SERVER[''REQUEST_URI''];
}else{
$url=$_SERVER[''SCRIPT_NAME''];
$url.=(!empty($_SERVER[''QUERY_STRING'']))?''?''.$_SERVER[''QUERY_STRING'']:'''';
}
return$url;
}

這個方法返回當前url的信息,這是我看國外很多人的cms系統這樣做,主要是緩存x.php?page=1,x.php?page=2,等這種文件的,這裡列出是為了擴展的這個cache類功能的.

functioncache_page($pageurl,$pagedata){
if(!$fso=fopen($pageurl,''w'')){
$this->warns(''無法打開緩存文件.'');//trigger_error
returnfalse;
}
if(!flock($fso,LOCK_EX)){//LOCK_NB,排它型鎖定
$this->warns(''無法鎖定緩存文件.'');//trigger_error
returnfalse;
}
if(!fwrite($fso,$pagedata)){//寫入位元組流,serialize寫入其他格式
$this->warns(''無法寫入緩存文件.'');//trigger_error
returnfalse;
}
flock($fso,LOCK_UN);//釋放鎖定
fclose($fso);
returntrue;
}

cache_page方法分別傳入的是緩存的文件名稱和數據,這是把數據寫到文件里的方法,先用fopen打開文件,然後調用句柄鎖定這個文件,然後用fwrite寫入文件,最後釋放這個句柄,任何一步發生錯誤將拋出錯誤.您可能看到這個註釋

 

寫入位元組流,serialize寫入其他格式

,順便一提的是如果我們要把一個數組,(可以從MySQL資料庫裡面select查詢除了的結果)用serialize函數寫入,用unserialize讀取到原來的類型.

functiondisplay_cache($cacheFile){
if(!file_exists($cacheFile)){
$this->warn(''無法讀取緩存文件.'');//trigger_error
returnfalse;
}
echo''讀取緩存文件:''.$cacheFile;
//returnunserialize(file_get_contents($cacheFile));
$fso=fopen($cacheFile,''r'');
$data=fread($fso,filesize($cacheFile));
fclose($fso);
return$data;
}

這是由文件名稱讀取緩存的方法,直接打開文件,讀取全部,如果文件不存在的或者無法讀取的話返回false,當然,你感到不人性的話,可以重新生成緩存.

functionreadData($cacheFile=''default_cache.txt''){
$cacheFile=$this->cache_dir."/".$cacheFile;
if(file_exists($cacheFile)&&filemtime($cacheFile)>(time()-$this->expireTime)){
$data=$this->display_cache($cacheFile);
}else{
$data="fromherewocangetitfrommysqldatabase,updatetimeis<b>".date(''ldSofFYh:i:sA'')."</b>,過期時間是:".date(''ldSofFYh:i:sA'',time()+$this->expireTime)."----------";
$this->cache_page($cacheFile,$data);
}
return$data;
}


這個函數是我們調用的方法,可以寫成介面的方法,由傳入參數判斷文件存在不,文件最後修改時間+expireTime的時間是不是過了當前時間(大於的話說明沒有過期),如果文件不存在或者已經過期,重新載入原始數據,這裡,為了簡單期間,我們是直接源是字元串,您可以把cache類繼承某類,取到資料庫的數據.(註釋2)

四:補充說明,結語 

註釋一:這個緩存的時間您可以自己調,可以根據時間情況讀取數組,xml,緩存等,請按照您的方便,值得一提的是緩存的時間(也就是緩存的key)也用緩存控制,.這在cms系統中被廣泛使用,他們把要更新的key放在緩存中,非常容易控制全戰.

註釋二:php5開始支持類繼承,這是讓人興奮的,把網站全局休息寫在一個配置的類裡面,再寫與數據層交互的類(如與MySQL交互的類),我們的這個cache類繼承數據交互的類,可以非常容易的讀取資料庫,這是外話,此處不再展開,有時間和大家詳談.

特別說明,這個類文件針對的php5以上版本,其他版本的請不要使用類.

 轉載自:http://www.aspnetjia.com
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 雖然西西不建議大家去用命令刪除資料庫表中的東西,但是這些刪除命令總有用的著的地方。 說到刪除表數據的關鍵字,大家記得最多的可能就是delete了 然而我們做資料庫開發,讀取資料庫數據.對另外的兩兄弟用得就比較少了 現在來介紹另外兩個兄弟,都是刪除表數據的,其實也是很容易理解的 老大------dro
  • 一、簡介 Chocolatey是Windows下包管理工具,可以使用 Chocolatey 來安裝應用程式。 二、安裝 1)線上安裝:參見 主頁 官網:https://chocolatey.org/ 2)離線安裝:下載腳本雙擊執行 http://files.cnblogs.com/files/274...
  • 我們知道UWP是通過不同的頁面來展示不同的內容的,那麼我們該怎麼進行頁面之間的傳值呢? 首先我們在MainPage裡面寫一個ListView來展示一些英文單詞。 1 List<English> wordList = new List<English> 2 { 3 new English { Word
  • List<Enterprise> epList = ViewBag.epList; foreach (var item in epList){ //todo ... } 當 List<Enterprise> epList = ViewBag.epList; 變為 List<EnterpriseInf
  • 鏈表的學習 在數據結構中有一種結構叫做線性表,線性表是儲存一個線性數據的表格,本文就簡要的介紹一下線性表的構成。 一、線性表的定義定義:由同種類型數據元素構成的有序數列的線性結構長度、表頭、表尾List線性表的形式有兩種:一種是數組構成的表,另一種是鏈表。所謂數組形成的表就是一個數組,如下定義所示
  • 在win10的環境下安裝scrapy,並不能直接按照官網的手冊(http://doc.scrapy.org/en/1.0/intro/install.html)一次性安裝成功,根據我自己的安裝過程中遇到的問題,特意整理了一下安裝過程 1.下載安裝python2.7.11 https://www.py...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...