• 技术文章 >后端开发 >php教程

    PHP 缓存实现代码及详细注释_PHP

    2016-06-01 12:18:19原创294
    复制代码 代码如下:
    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 {

    protected $_cachesDir = 'cache';

    public function __construct() {
    if (defined('DATA_DIR')) {
    $this->_setCacheDir(DATA_DIR . '/cache');
    }
    }

    /**
    * 获取缓存文件
    *
    * @param string $key
    * @return string
    */
    protected function _getCacheFile($key) {
    return $this->_cachesDir . '//m.sbmmt.com/m/' . substr($key, 0, 2) . '//m.sbmmt.com/m/' . $key . '.php';
    }
    /**
    * 读取缓存变量
    * 为防止信息泄露,缓存文件格式为php文件,并以""开头
    *
    * @param string $key 缓存下标
    * @return mixed
    */
    public function fetch($key) {
    $cacheFile = self::_getCacheFile($key);
    if (file_exists($cacheFile) && is_readable($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" target="_blank">!@mkdir($cacheDir, 0755, true)) {
    throw new CacheException("Could not make cache directory");
    }
    }
    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($cacheFile" target="_blank">!@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" target="_blank">!@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 $this;
    }
    /**
    * 设置文件缓存目录
    * @param string $dir
    * @return Cache_File
    */
    protected function _setCacheDir($dir) {
    $this->_cachesDir = rtrim(str_replace('\\', '//m.sbmmt.com/m/', trim($dir)), '//m.sbmmt.com/m/');
    clearstatcache();
    if(!is_dir($this->_cachesDir)) {
    mkdir($this->_cachesDir, 0755, true);
    }
    //
    return $this;
    }

    /**
    * 清空所有缓存
    *
    * @return Cache_File
    */
    public function clear() {
    // 遍历目录清除缓存
    $cacheDir = $this->_cachesDir;
    $d = dir($cacheDir);
    while(false !== ($entry = $d->read())) {
    if('.' == $entry[0]) {
    continue;
    }

    $cacheEntry = $cacheDir . '//m.sbmmt.com/m/' . $entry;
    if(is_file($cacheEntry)) {
    @unlink($cacheEntry);
    } elseif(is_dir($cacheEntry)) {
    // 缓存文件夹有两级
    $d2 = dir($cacheEntry);
    while(false !== ($entry = $d2->read())) {
    if('.' == $entry[0]) {
    continue;
    }

    $cacheEntry .= '//m.sbmmt.com/m/' . $entry;
    if(is_file($cacheEntry)) {
    @unlink($cacheEntry);
    }
    }
    $d2->close();
    }
    }
    $d->close();

    return $this;
    }
    }
    /**
    * 缓存单元的数据结构
    * array(
    * 'time' => time(), // 缓存写入时的时间戳
    * 'expire' => $expire, // 缓存过期时间
    * 'valid' => true, // 缓存是否有效
    * 'data' => $value // 缓存的值
    * );
    */
    final class Cache {
    /**
    * 缓存过期时间长度(s)
    *
    * @var int
    */
    private $_expire = 3600;
    /**
    * 缓存处理类
    *
    * @var Cache_Abstract
    */
    private $_storage = null;
    /**
    * @return Cache
    */
    static public function createCache($cacheClass = 'Cache_File') {
    return new self($cacheClass);
    }
    private function __construct($cacheClass) {
    $this->_storage = new $cacheClass();
    }
    /**
    * 设置缓存
    *
    * @param string $key
    * @param mixed $value
    * @param int $expire
    */
    public function set($key, $value, $expire = false) {
    if (!$expire) {
    $expire = $this->_expire;
    }

    $this->_storage->checkLock($key);

    $data = array('time' => time(), 'expire' => $expire, 'valid' => true, 'data' => $value);
    $this->_storage->lock($key);

    try {
    $this->_storage->store($key, $data);
    $this->_storage->unlock($key);
    } catch (CacheException $e) {
    $this->_storage->unlock($key);
    throw $e;
    }
    }
    /**
    * 读取缓存
    *
    * @param string $key
    * @return mixed
    */
    public function get($key) {
    $data = $this->fetch($key);
    if ($data && $data['valid'] && !$data['isExpired']) {
    return $data['data'];
    }

    return false;
    }
    /**
    * 读缓存,包括过期的和无效的,取得完整的存贮结构
    *
    * @param string $key
    */
    public function fetch($key) {
    $this->_storage->checkLock($key);
    $data = $this->_storage->fetch($key);
    if ($data) {
    $data['isExpired'] = (time() - $data['time']) > $data['expire'] ? true : false;
    return $data;
    }

    return false;
    }
    /**
    * 删除缓存
    *
    * @param string $key
    */
    public function delete($key) {
    $this->_storage->checkLock($key)
    ->lock($key)
    ->delete($key)
    ->unlock($key);
    }

    public function clear() {
    $this->_storage->clear();
    }
    /**
    * 把缓存设为无效
    *
    * @param string $key
    */
    public function setInvalidate($key) {
    $this->_storage->checkLock($key)
    ->lock($key);
    try {
    $data = $this->_storage->fetch($key);
    if ($data) {
    $data['valid'] = false;
    $this->_storage->store($key, $data);
    }
    $this->_storage->unlock($key);
    } catch (CacheException $e) {
    $this->_storage->unlock($key);
    throw $e;
    }
    }

    /**
    * 设置缓存过期时间(s)
    *
    * @param int $expire
    */
    public function setExpire($expire) {
    $this->_expire = (int) $expire;
    return $this;
    }
    }
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:PHP 缓存
    上一篇:php imagecreatetruecolor 创建高清和透明图片代码小结_PHP 下一篇:php radio 单选框获取与保持值的实现代码_PHP
    Web大前端开发直播班

    相关文章推荐

    • PHP程序员的调试技术_PHP教程• PHP+Java的开发经验:不要太面向对象_PHP教程• 通过PHP来实现登录验证码功能_PHP教程• PHP中实现页面跳转实例_PHP教程• 基于PHP编程注意事项的小结_PHP教程

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网