php缓存技术详细介绍及php缓存实现代码

作者:袖梨 2022-06-24

数据缓存:这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓存表或文件中获得。

用的最广的例子看Discuz的搜索功能,把结果ID缓存到一个表中,下次搜索相同关键字时先搜索缓存表。

举个常用的方法,多表关联的时候,把附表中的内容生成数组保存到主表的一个字段中,需要的时候数组分解一下,这样的好处是只读一个表,坏处就是两个数据同步会多不少步骤,数据库永远是瓶颈,用硬盘换速度,是这个的关键点。

页面缓存:

每次访问页面的时候,都会先检测相应的缓存页面文件是否存在,如果不存在,就连接数据库,得到数据,显示页面并同时生成缓存页面文件,这样下次访问的时候页面文件就发挥作用了。(模板引擎和网上常见的一些PHP缓存机制类通常有此功能)

时间触发缓存:

检查文件是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存。

内容触发缓存:

当插入数据或更新数据时,强制更新PHP缓存机制。

静态缓存:

这里所说的静态缓存是指静态化,直接生成HTML或XML等文本文件,有更新的时候重生成一次,适合于不太变化的页面,这就不说了。

以上内容是代码级的解决方案,我直接CP别的框架,也懒得改,内容都差不多,很容易就做到,而且会几种方式一起用,但下面的内容是服务器端的缓存方案,非代码级的,要有多方的合作才能做到

内存缓存:

Memcached是高性能的,分布式的内存对象PHP缓存机制系统,用于在动态应用中减少数据库负载,提升访问速度。

php的缓冲器:

有eaccelerator, apc, phpa,xcache,这个这个就不说了吧,搜索一堆一堆的,自己看啦,知道有这玩意就OK

MYSQL缓存:

这也算非代码级的,经典的数据库就是用的这种方式,看下面的运行时间,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 {}  
/** 
 * 缓存抽象类 
 */  
abstract class Cache_Abstract {  
    /** 
     * 读缓存变量 
     * 
     * @param string $key 缓存下标 
     * @return mixed 
     */  
    abstract public function fetch($key);  
      
    /** 
     * 缓存变量 
     * 
     * @param string $key 缓存变量下标 
     * @param string $value 缓存变量的值 
     * @return bool 
     */  
    abstract public function store($key, $value);  
      
    /** 
     * 删除缓存变量 
     * 
     * @param string $key 缓存下标 
     * @return Cache_Abstract 
     */  
    abstract public function delete($key);  
      
    /** 
     * 清(删)除所有缓存 
     * 
     * @return Cache_Abstract 
     */  
    abstract public function clear();  
      
    /** 
     * 锁定缓存变量 
     * 
     * @param string $key 缓存下标 
     * @return Cache_Abstract 
     */  
    abstract public function lock($key);  
  
    /** 
     * 缓存变量解锁 
     * 
     * @param string $key 缓存下标 
     * @return Cache_Abstract 
     */  
    abstract public function unlock($key);  
  
    /** 
     * 取得缓存变量是否被锁定 
     * 
     * @param string $key 缓存下标 
     * @return bool 
     */  
    abstract public function isLocked($key);  
  
    /** 
     * 确保不是锁定状态 
     * 最多做$tries次睡眠等待解锁,超时则跳过并解锁 
     * 
     * @param string $key 缓存下标 
     */  
    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扩展缓存实现 
 *  
 *  
 * @category   Mjie 
 * @package    Cache 
 * @author     流水孟春 
 * @copyright  Copyright (c) 2008-  
 * @license    New BSD License 
 * @version    $Id: Cache/Apc.php 版本号 2010-04-18 23:02 cmpan $ 
 */  
class Cache_Apc extends Cache_Abstract {  
      
    protected $_prefix = 'cache.mjie.net';  
      
    public function __construct() {  
        if (!function_exists('apc_cache_info')) {  
            throw new CacheException('apc extension didn't installed');  
        }  
    }  
      
    /** 
     * 保存缓存变量 
     * 
     * @param string $key 
     * @param mixed $value 
     * @return bool 
     */  
    public function store($key, $value) {  
        return apc_store($this->_storageKey($key), $value);  
    }  
      
    /** 
     * 读取缓存 
     * 
     * @param string $key 
     * @return mixed 
     */  
    public function fetch($key) {  
        return apc_fetch($this->_storageKey($key));  
    }  
      
    /** 
     * 清除缓存 
     * 
     * @return Cache_Apc 
     */  
    public function clear() {  
        apc_clear_cache();  
        return $this;  
    }  
      
    /** 
     * 删除缓存单元 
     * 
     * @return Cache_Apc 
     */  
    public function delete($key) {  
        apc_delete($this->_storageKey($key));  
        return $this;  
    }  
      
    /** 
     * 缓存单元是否被锁定 
     * 
     * @param string $key 
     * @return bool 
     */  
    public function isLocked($key) {  
        if ((apc_fetch($this->_storageKey($key) . '.lock')) === false) {  
            return false;  
        }  
          
        return true;  
    }  
      
    /** 
     * 锁定缓存单元 
     * 
     * @param string $key 
     * @return Cache_Apc 
     */  
    public function lock($key) {  
        apc_store($this->_storageKey($key) . '.lock', '', 5);  
        return $this;  
    }  
      
    /** 
     * 缓存单元解锁 
     * 
     * @param string $key 
     * @return Cache_Apc 
     */  
    public function unlock($key) {  
        apc_delete($this->_storageKey($key) . '.lock');  
        return $this;  
    }  
      
    /** 
     * 完整缓存名 
     * 
     * @param string $key 
     * @return string 
     */  
    private function _storageKey($key) {  
        return $this->_prefix . '_' . $key;  
    }  
}  
  
/** 
 * 文件缓存实现 
 *  
 *  
 * @category   Mjie 
 * @package    Cache 
 * @author     流水孟春 
 * @copyright  Copyright (c) 2008-  
 * @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 = 'cache';  
      
    public function __construct() {  
        if (defined('DATA_DIR')) {  
            $this->_setCacheDir(DATA_DIR . '/cache');  
        }  
    }  
      
    /** 
     * 获取缓存文件 
     * 
     * @param string $key 
     * @return string 
     */  
    protected function _getCacheFile($key) {  
        $subdir = $this->useSubdir ? substr($key, 0, 2) . '/' : '';  
        return $this->_cachesDir . '/' . $subdir . $key . '.php';  
    }  
  
    /** 
     * 读取缓存变量 
     * 为防止信息泄露,缓存文件格式为php文件,并以""开头 
     *  
     * @param string $key 缓存下标 
     * @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;  
    }  
  
    /** 
     * 缓存变量 
     * 为防止信息泄露,缓存文件格式为php文件,并以""开头 
     * 
     * @param string $key 缓存变量下标 
     * @param string $value 缓存变量的值 
     * @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, '   
        return @file_put_contents($cacheFile, '' . serialize($value));  
    }  
  
    /** 
     * 删除缓存变量 
     * 
     * @param string $key 缓存下标 
     * @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;  
    }  
  
    /** 
     * 缓存单元是否已经锁定 
     * 
     * @param string $key 
     * @return bool 
     */  
    public function isLocked($key) {  
        $cacheFile = self::_getCacheFile($key);  
        clearstatcache();  
        return file_exists($cacheFile . '.lock');  
    }  
  
    /** 
     * 锁定 
     * 
     * @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");  
                }  
            }  
        }  
  
        // 设定缓存锁文件的访问和修改时间  
        @touch($cacheFile . '.lock');  
        return $this;  
    }  
    
    /** 
     * 解锁 
     * 
     * @param string $key 
     * @return Cache_File 
     */  
    public function unlock($key) {  
        $cacheFile = self::_getCacheFile($key);  
        @unlink($cacheFile . '.lock');  
        return 

相关文章

精彩推荐