首頁 > 後端開發 > php教程 > php快取技術詳細介紹及php快取的實作程式碼

php快取技術詳細介紹及php快取的實作程式碼

高洛峰
發布: 2016-11-29 10:18:47
原創
990 人瀏覽過

有些資訊比方經常不變的,但是還是能變的資訊放在快取中以加快顯示速度,這是很有價值的,所謂的快取,通俗的理解就是一些保存在伺服器端的共用資訊.它是於伺服器同生死的,我們在保存快取的時候可以指定下次更新的時間的判斷,比方要在5分鐘更新一次

資料快取:這裡所說的資料快取是指資料庫查詢PHP快取機制,每次訪問頁面的時候,都會先檢測相應的快取資料是否存在,如果不存在,就連接資料庫,得到數據,並把查詢結果序列化後保存到文件中,以後同樣的查詢結果就直接從快取表或文件中獲得。

用的最廣的例子看Discuz的搜尋功能,把結果ID快取到一個表中,下次搜尋相同關鍵字時先搜尋快取表。

舉個常用的方法,多表關聯的時候,把附表中的內容生成數組保存到主表的一個字段中,需要的時候數組分解一下,這樣的好處是只讀一個表,壞處就是兩個資料同步會多不少步驟,資料庫永遠是瓶頸,用硬碟換速度,是這個的關鍵點。

頁面快取:

每次訪問頁面的時候,都會先檢測相應的快取頁面文件是否存在,如果不存在,就連接資料庫,得到數據,顯示頁面並同時產生快取頁面文件,這樣下次造訪的時候頁面文件就發揮作用了。 (模板引擎和網路上常見的一些PHP快取機制類別通常有此功能)

時間觸發快取:

檢查檔案是否存在且時間戳小於設定的過期時間,如果檔案修改的時間戳比當前時間戳減去過期時間戳大,那麼就用緩存,否則更新快取。

內容觸發快取:

當插入資料或更新資料時,強制更新PHP快取機制。

靜態快取:

這裡所說的靜態快取是指靜態化,直接產生HTML或XML等文字文件,有更新的時候重生成一次,適合於不太變化的頁面,這就不說了。

以上內容是程式碼級的解決方案,我直接CP別的框架,也懶得改,內容都差不多,很容易就做到,而且會幾種方式一起用,但下面的內容是伺服器端的快取方案,非程式碼級的,要有多方的合作才能做到

記憶體快取:

Memcached是高效能的,分散式的記憶體物件PHP快取機制系統,用於在動態應用中減少資料庫負載,提升存取速度。

php的緩衝器:

有eaccelerator, apc, phpa,xcache,這個這個就不說了吧,搜尋有eaccelerator, apc, phpa,xcache,這個這個就不說了吧,搜尋有eaccelerator, apc, phpa,xcache,這個這個就不說了吧,搜尋有eaccelerator, apc, phpa,xcache,這個這個就不說了吧,搜尋有eaccelerator,apc,知道有這玩意就

MY這也算非代碼級的,經典的資料庫就是用的這種方式,看下面的運行時間,0.09xxx之類的

我貼段根據藍色那傢伙修改後部分my.ini吧,2G的MYISAM表可以在0.05S左右,據說他前後改了有快一年


基於反向代理的Web緩存:

如Nginx,SQUID,mod_proxy(apache2以上又分為mod_proxy和mod_cache)

NGINX的例子

用google找到一些php快取技術方法

發個PHP快取實現,實現了apc和檔案緩存,繼承Cache_Abstract即可實現呼叫第三方的快取工具。

參考shindig的快取類別和apc。

<?php   
class CacheException extends Exception {}   
/**  
 * <a href="http://www.php.cn/category/79.html">缓存</a>抽象类  
 */  
abstract class Cache_Abstract {   
    /**  
     * 读<a href="http://www.php1.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return mixed  
     */  
    abstract public function fetch($key);   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>变量下标  
     * @param string $value <a href="http://www.php.cn/category/79.html">缓存</a>变量的值  
     * @return bool  
     */  
    abstract public function store($key, $value);   
        
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function delete($key);   
        
    /**  
     * 清(删)除所有<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @return Cache_Abstract  
     */  
    abstract public function clear();   
        
    /**  
     * 锁定<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function lock($key);   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量解锁  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_Abstract  
     */  
    abstract public function unlock($key);   
    
    /**  
     * 取得<a href="http://www.php.cn/category/79.html">缓存</a>变量是否被锁定  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return bool  
     */  
    abstract public function isLocked($key);   
    
    /**  
     * 确保不是锁定状态  
     * 最多做$tries次睡眠等待解锁,超时则跳过并解锁  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     */  
    public function checkLock($key) {   
        if (!$this->isLocked($key)) {   
            return $this;   
        }   
            
        $tries = 10;   
        $count = 0;   
        do {   
            usleep(200);   
            $count ++;   
        } while ($count <= $tries && $this->isLocked($key));  // 最多做十次睡眠等待解锁,超时则跳过并解锁   
    
        $this->isLocked($key) && $this->unlock($key);   
            
        return $this;   
    }   
}   
    
    
/**  
 * APC扩展<a href="http://www.php.cn/category/79.html">缓存</a>实现  
 *   
 *   
 * @category   Mjie  
 * @package    Cache  
 * @author     流水孟春  
 * @copyright  Copyright (c) 2008- <cmpan(at)qq.com>  
 * @license    New BSD License  
 * @version    $Id: Cache/Apc.php 版本号 2010-04-18 23:02 cmpan $  
 */  
class Cache_Apc extends Cache_Abstract {   
        
    protected $_prefix = &#39;cache.mjie.net&#39;;   
        
    public function __construct() {   
        if (!function_exists(&#39;apc_cache_info&#39;)) {   
            throw new CacheException(&#39;apc extension didn&#39;t installed&#39;);   
        }   
    }   
        
    /**  
     * 保存<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key  
     * @param mixed $value  
     * @return bool  
     */  
    public function store($key, $value) {   
        return apc_store($this->_storageKey($key), $value);   
    }   
        
    /**  
     * 读取<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @param string $key  
     * @return mixed  
     */  
    public function fetch($key) {   
        return apc_fetch($this->_storageKey($key));   
    }   
        
    /**  
     * 清除<a href="http://www.php.cn/category/79.html">缓存</a>  
     *  
     * @return Cache_Apc  
     */  
    public function clear() {   
        apc_clear_cache();   
        return $this;   
    }   
        
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>单元  
     *  
     * @return Cache_Apc  
     */  
    public function delete($key) {   
        apc_delete($this->_storageKey($key));   
        return $this;   
    }   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元是否被锁定  
     *  
     * @param string $key  
     * @return bool  
     */  
    public function isLocked($key) {   
        if ((apc_fetch($this->_storageKey($key) . &#39;.lock&#39;)) === false) {   
            return false;   
        }   
            
        return true;   
    }   
        
    /**  
     * 锁定<a href="http://www.php.cn/category/79.html">缓存</a>单元  
     *  
     * @param string $key  
     * @return Cache_Apc  
     */  
    public function lock($key) {   
        apc_store($this->_storageKey($key) . &#39;.lock&#39;, &#39;&#39;, 5);   
        return $this;   
    }   
        
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元解锁  
     *  
     * @param string $key  
     * @return Cache_Apc  
     */  
    public function unlock($key) {   
        apc_delete($this->_storageKey($key) . &#39;.lock&#39;);   
        return $this;   
    }   
        
    /**  
     * 完整<a href="http://www.php.cn/category/79.html">缓存</a>名  
     *  
     * @param string $key  
     * @return string  
     */  
    private function _storageKey($key) {   
        return $this->_prefix . &#39;_&#39; . $key;   
    }   
}   
    
/**  
 * 文件<a href="http://www.php.cn/category/79.html">缓存</a>实现  
 *   
 *   
 * @category   Mjie  
 * @package    Cache  
 * @author     流水孟春  
 * @copyright  Copyright (c) 2008- <cmpan(at)qq.com>  
 * @license    New BSD License  
 * @version    $Id: Cache/File.php 版本号 2010-04-18 16:46 cmpan $  
 */  
class Cache_File extends Cache_Abstract {   
    public $useSubdir     = false;   
        
    protected $_cachesDir = &#39;cache&#39;;   
        
    public function __construct() {   
        if (defined(&#39;DATA_DIR&#39;)) {   
            $this->_setCacheDir(DATA_DIR . &#39;/cache&#39;);   
        }   
    }   
        
    /**  
     * 获取<a href="http://www.php.cn/category/79.html">缓存</a>文件  
     *  
     * @param string $key  
     * @return string  
     */  
    protected function _getCacheFile($key) {   
        $subdir = $this->useSubdir ? substr($key, 0, 2) . &#39;/&#39; : &#39;&#39;;   
        return $this->_cachesDir . &#39;/&#39; . $subdir . $key . &#39;.php&#39;;   
    }   
    
    /**  
     * 读取<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     * 为防止信息泄露,<a href="http://www.php.cn/category/79.html">缓存</a>文件格式为php文件,并以"<?php exit;?>"开头  
     *   
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return mixed  
     */  
    public function fetch($key) {   
        $cacheFile = self::_getCacheFile($key);   
        if (file_exists($cacheFile) && is_readable($cacheFile)) {   
            // include 方式   
            //return include $cacheFile;   
            // 系列化方式   
    
            return unserialize(@file_get_contents($cacheFile, false, NULL, 13));   
        }   
    
        return false;   
    }   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>变量  
     * 为防止信息泄露,<a href="http://www.php.cn/category/79.html">缓存</a>文件格式为php文件,并以"<?php exit;?>"开头  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>变量下标  
     * @param string $value <a href="http://www.php.cn/category/79.html">缓存</a>变量的值  
     * @return bool  
     */  
    public function store($key, $value) {   
        $cacheFile = self::_getCacheFile($key);   
        $cacheDir  = dirname($cacheFile);   
    
        if(!is_dir($cacheDir)) {   
            if(!@mkdir($cacheDir, 0755, true)) {   
                throw new CacheException("Could not make cache directory");   
            }   
        }   
    // 用include方式   
        //return @file_put_contents($cacheFile, &#39;<?php return &#39; . var_export($value, true). &#39;;&#39;);   
    
        return @file_put_contents($cacheFile, &#39;<?php exit;?>&#39; . serialize($value));   
    }   
    
    /**  
     * 删除<a href="http://www.php.cn/category/79.html">缓存</a>变量  
     *  
     * @param string $key <a href="http://www.php.cn/category/79.html">缓存</a>下标  
     * @return Cache_File  
     */  
    public function delete($key) {   
        if(emptyempty($key)) {   
            throw new CacheException("Missing argument 1 for Cache_File::delete()");   
        }   
            
        $cacheFile = self::_getCacheFile($key);   
        if(!@unlink($cacheFile)) {   
            throw new CacheException("Cache file could not be deleted");   
        }   
    
        return $this;   
    }   
    
    /**  
     * <a href="http://www.php.cn/category/79.html">缓存</a>单元是否已经锁定  
     *  
     * @param string $key  
     * @return bool  
     */  
    public function isLocked($key) {   
        $cacheFile = self::_getCacheFile($key);   
        clearstatcache();   
        return file_exists($cacheFile . &#39;.lock&#39;);   
    }   
    
    /**  
     * 锁定  
     *  
     * @param string $key  
     * @return Cache_File  
     */  
    public function lock($key) {   
        $cacheFile = self::_getCacheFile($key);   
        $cacheDir  = dirname($cacheFile);   
        if(!is_dir($cacheDir)) {   
            if(!@mkdir($cacheDir, 0755, true)) {   
                if(!is_dir($cacheDir)) {   
                    throw new CacheException("Could not make cache directory");   
                }   
            }   
        }   
    
        // 设定<a href="http://www.php.cn/category/79.html">缓存</a>锁文件的访问和修改时间   
        @touch($cacheFile . &#39;.lock&#39;);   
        return $this;   
    }   
      
    /**  
     * 解锁  
     *  
     * @param string $key  
     * @return Cache_File  
     */  
    public function unlock($key) {   
        $cacheFile = self::_getCacheFile($key);   
        @unlink($cacheFile . &#39;.lock&#39;);   
        return
登入後複製

相關標籤:
php
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板