PHP利於學習,使用廣泛,主要適用於Web開發領域。以下是為大家分享的php頁面快取實現方法,供大家參考借鑑,歡迎瀏覽!
在php頁面快取主要用到的是ob系列函式,如ob_start(),ob_end_flush(),ob_get_contents(),但是更高階的快取是不使用這些函式的,本文章最後一個實現就有講到,大家可參考一下。
ob_start():頁面快取開始的標誌,此函式一下的內容直至ob_end_flush()或者ob_end_clean()都儲存在頁面快取中;
ob_get_contents():用來獲取頁面快取中的內容,獲取到以後呢,我們就可以想怎麼處理這些內容都行了,過濾欄位啦,匹配內容啦,都可以~~~ :)
ob_end_flush():表示頁面快取結束。並且經我驗證,快取的內容將輸出到當前頁面上,也就是可以顯示快取內容。
用此三個php函式,就可以實現強大的.功能。如果資料庫查詢量較大,可以用cache來解決這個問題。
下面是編碼部分。
1.初始化函式,一般是設定頁面快取路徑、快取檔案命名格式等,可按個人喜好自定義。這裡用到的識別ID是經加密的$_SERVER[REQUEST_URI]引數。這個函式中最後還有一個if判斷:若未過快取期,則載入快取檔案,否則載入原始檔。
程式碼如下
function page_init()
{
$url = $_SERVER['REQUEST_URI'];//子url,該引數一般是唯一的
$pageid = md5($url);
$dir = str_replace('/','_',substr($_SERVER['SCRIPT_NAME'],1,-4));
//目錄命名方式,如exp_index
if(!file_exists($pd = PAGE_PATH.$dir.'/'))@mkdir($pd,0777) or die("$pd目錄建立失敗");
//如cache/page/exp_index/
define('PAGE_FILE',$pd.$pageid.'');
//如cache/page/exp_index/
$contents = file_get_contents(PAGE_FILE);//讀出
if($contents && substr($contents, 13, 10) > time() )//對應page_cache()函式中加上的自定義頭部
{
echo substr($contents, 27);
exit(0);
}
return true;
}
2.頁面快取函式,這裡使用到一個技巧:在快取檔案的內容中加上一個頭部資訊--過期時間,所以每次只需要對頭部中的過期時間和當前時間進行比較(在page_init()函式中進行)就能判斷快取是否過期了。
程式碼如下
function page_cache($ttl = 0)
{
$ttl = $ttl ? $ttl : PAGE_TTL;//快取時間,預設3600s
$contents = ob_get_contents();//從快取中獲取內容
$contents = "<!--page_ttl:".(time() + $ttl)."-->n".$contents;
//加上自定義頭部:過期時間=生成時間+快取時間
file_put_contents(PAGE_FILE, $contents);//寫入快取檔案中
ob_end_flush();//釋放快取
}
3.函式使用,注意這兩個函式有先後執行順序,還有別忘了ob_start()
程式碼如下
<?php
page_init();//頁面快取初始化
ob_start();//開啟快取
...//程式碼段
page_cache(60);//一般是最後一行
?>
例2
下面做個示例來說明PHP頁面快取技術:
程式碼如下
<?php
$_time =10;
$dir="D:php";
function cache_start($_time, $dir)
{
$cachefile = $dir.'/'1($_SERVER['REQUEST_URI']).'';
$cachetime = $_time;
ob_start();
if(file_exists($cachefile) && (time()-filemtime($cachefile) < $cachetime))
{
include($cachefile);
ob_end_flush();
exit;
}
}
function cache_end($dir)
{
$cachefile = $dir.'/'1($_SERVER['REQUEST_URI']).'';
$fp = fopen($cachefile, 'w');
fwrite($fp, ob_get_contents());
fclose($fp);
ob_end_flush();
}
cache_start($_time, $dir);
//以下是輸出的內容,放在cache_start和cache_end兩個方法之間
for ($i=0;$i<5;$i++)
{
echo $i;
sleep(1);
}
cache_end($dir);
?>
例
利用生成檔案做快取
程式碼如下
<?php
ob_start();
/**
* @author 何名慧
* @copyright 2009-3-13
* @param string $cache_folder 緩資料夾
* @param int $cache_create_time 檔案快取時間
* @example $cache=new Esj_Cache('./_cache',100)
* @example $cache->read_cache() 讀取快取並輸出
* @example $cache->creatre_cache() 建立快取檔案(放在檔案未尾)
* @example $cache->list_file() 返回所有快取檔案列表
* @example $cache->del_file() 刪除所有快取檔案
*/
class Esj_Cache{
private $cache_folder=null;//cacher資料夾
private $wroot_dir=null;//站點目錄
private $cacher_create_time=null;//cacher檔案的建立時間
public function __construct($cache_foldername,$cacher_time=100)
{
ob_start();
$this->wroot_dir=$_SERVER['DOCUMENT_ROOT'];
$this->cache_folder=$cache_foldername;
$this->cacher_create_time=$cacher_time;
}
public function read_cache()
{
try {
if(self::create_folder($this->cache_folder))
{
self::get_cache();//輸出快取檔案資訊
}else
{
echo "快取資料夾建立失敗!";
return false;
}
}catch(Exception $e){
echo $e;
return false;
}
}
//測試快取資料夾是否存在
private function exist_folder($foler)
{
if(file_exists($this->wroot_dir."/".$foler)){
return true;
}else {
return false;
}
}
//建立一個新的資料夾
private function create_folder($foler)
{
if(!self::exist_folder($foler))
{
try{
mkdir($this->wroot_dir."/".$foler,0777);
chmod($this->wroot_dir."/".$foler,0777);
return true;
}catch (Exception $e)
{
self::get_cache();//輸出快取
return false;
}
return false;
}
else
{
return true;
}
}
//讀取快取檔案
private function get_cache()
{
$file_name=self::get_filename();
if (file_exists($file_name)&&((filemtime($file_name)+$this->cacher_create_time) > time()))
{
$content=file_get_contents($file_name);
if($content)
{
echo $content;
ob_end_flush();
exit;
}else
{
echo "檔案讀取失敗";
exit;
}
}
}
//返回檔案的名字
private function get_filename()
{
$filename=$file_name=$this->wroot_dir.'/'.$this->cache_folder.'/'5($_SERVER['QUERY_STRING'])."";
return $filename;
}
//建立快取檔案
public function create_cache()
{
$filename=self::get_filename();
if($filename!="")
{
try{
file_put_contents($filename,ob_get_contents());
return true;
}catch (Exception $e)
{
echo "寫快取失敗:".$e;
exit();
}
return true;
}
}
// 取得快取中的所有檔案
public function list_file()
{
$path=$this->cache_folder;
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if($file!="." && $file!="..") {
$path1=$path."/".$file;
if(file_exists($path1))
{
$result[]=$file;
}
}
}
closedir($handle);
}
return $result;
}
//刪除快取中的所有檔案
public function del_file()
{
$path=$this->cache_folder;
if ($handle = opendir($path)) {
while (false !== ($file = readdir($handle))) {
if($file!="." && $file!="..") {
$path1=$path."/".$file;
if(file_exists($path1))
{
unlink($path1);
}
}
}
closedir($handle);
}
return true;
}
}
?>