Zend_Cache_Core 注解

本文介绍 Zend_Cache_Core 类的详细实现,包括缓存的读取、写入、验证、清理等功能,并解析其配置选项及后端模块交互方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class Zend_Cache_Core
{

    
// ------------------
    // --- Properties ---
    // ------------------


    
/**
     * Backend Object 保存采用后端实例
     *
     * @var object
     
*/
    
private $_backend = null;

    
/**
     * Available options
     *
     * ====> (boolean) write_control : 
     * - Enable / disable write control (the cache is read just after writing to detect corrupt entries)
     * - Enable write control will lightly slow the cache writing but not the cache reading
     * Write control can detect some corrupt cache files but maybe it's not a perfect control
     * 写入时检测要缓存的内容与原来的内容是否一致 
     * 
     * ====> (boolean) caching :    是否要缓存的开关
     * - Enable / disable caching
     * (can be very usefull for the debug of cached scripts)
     *  可以在调试程序时关闭缓存开关
     * 
     * ====> (boolean) automatic_serialization : 自动序列化开关
     * - Enable / disable automatic serialization
     * - It can be used to save directly datas which aren't strings (but it's slower)
     * 开启后可以实现保存非字符窜类型数据
     * 
     * ====> (int) automatic_cleaning_factor :    自动清理过期缓存开关
     * - Disable / Tune the automatic cleaning process
     * - The automatic cleaning process destroy too old (for the given life time)
     *   cache files when a new cache file is written :
     *     0               => no automatic cache cleaning
     *     1               => systematic cache cleaning
     *     x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
     *
     * ====> (int) lifetime :    缓存存在的时间
     * - Cache lifetime (in seconds)
     * - If null, the cache is valid forever. 为空表示缓存不过期
     *
     * ====> (boolean) logging :    日志开关
     * - If set to true, logging is activated (but the system is slower)
     *
     * @var array available options
     
*/
    
protected $_options = array(
        
'write_control'             => true,
        
'caching'                   => true,
        
'automatic_serialization'   => false,
        
'automatic_cleaning_factor' => 10,
        
'lifetime'                  => 3600,
        
'logging'                   => false,
        
'logger'                    => null
    );

    
/**
     * Array of options which have to be transfered to backend 设置需要传递给后台模块的参数
     
*/
    
protected static $_directivesList = array('lifetime', 'logging', 'logger');

    
/**
     * Not used for the core, just a sort a hint to get a common setOption() method (for the core and for frontends)
     
*/
    
protected $_specificOptions = array();

    
/**
     * Last used cache id
     * 最后一次使用的缓冲id
     * 
     * @var string $_lastId
     
*/
    
private $_lastId = null;

    
/**
     * backward compatibility becase of ZF-879 and ZF-1172 (it will be removed in ZF 1.1)
     * 针对后台模块为兼容早期 zf  版本的设置
     * @var array
     
*/
    
protected $_backwardCompatibilityArray = array(
        
'lifeTime' => 'lifetime',
        
'writeControl' => 'write_control',
        
'automaticSerialization' => 'automatic_serialization',
        
'automaticCleaningFactor' => 'automatic_cleaning_factor',
        
'cachedEntity' => 'cached_entity',
        
'cacheByDefault' => 'cache_by_default',
        
'cachedMethods' => 'cached_methods',
        
'nonCachedMethods' => 'non_cached_methods',
        
'cachedFunctions' => 'cached_functions',
        
'nonCachedFunctions' => 'non_cached_functions',
        
'masterFile' => 'master_file',
        
'httpConditional' => 'http_conditional',
        
'debugHeader' => 'debug_header',
        
'defaultOptions' => 'default_options',
        
'cacheWithGetVariables' => 'cache_with_get_variables',
        
'cacheWithPostVariables' => 'cache_with_post_variables',
        
'cacheWithSessionVariables' => 'cache_with_session_variables',
        
'cacheWithFilesVariables' => 'cache_with_files_variables',
        
'cacheWithCookieVariables' => 'cache_with_cookie_variables',
        
'makeIdWithGetVariables' => 'make_id_with_get_variables',
        
'makeIdWithPostVariables' => 'make_id_with_post_variables',
        
'makeIdWithSessionVariables' => 'make_id_with_session_variables',
        
'makeIdWithFilesVariables' => 'make_id_with_files_variables',
        
'makeIdWithCookieVariables' => 'make_id_with_cookie_variables'
    );

    
// ----------------------
    // --- Public methods ---
    // ----------------------


    
/**
     * Constructor
     *
     * @param array $options associative array of options
     
*/
    
public function __construct($options = array())
    {
        
if (!is_array($options)) {
            Zend_Cache
::throwException('Options parameter must be an array');
        }
        
while (list($name, $value= each($options)) {
            
$this->setOption($name, $value);
        }
        
$this->_loggerSanity();
    }

    
/**
     * Set the backend
     *
     * @param object $backendObject
     
*/
    
public function setBackend($backendObject)
    {
        
if (!is_object($backendObject)) {
            Zend_Cache
::throwException('Incorrect backend object !');
        }
        
$this->_backend= $backendObject;
        
// some options (listed in $_directivesList) have to be given
        // to the backend too (even if they are not "backend specific")

        $directives = array();
        
foreach (Zend_Cache_Core::$_directivesList as $directive) {
            
$directives[$directive= $this->_options[$directive];
        }
        
$this->_backend->setDirectives($directives);
    }

    
/**
     * Public frontend to set an option
     *
     * There is an additional validation (relatively to the protected _setOption method)
     *
     * @param string $name name of the option
     * @param mixed $value value of the option
     
*/
    
public function setOption($name, $value)
    {
        
if (is_string($name)) {
            
if (array_key_exists($name, $this->_backwardCompatibilityArray)) {
                
$tmp = $this->_backwardCompatibilityArray[$name];
                
$this->_log("$name option is deprecated, use $tmp instead (same syntax) !");
                
$name = $tmp;
            } 
else {
                
$name = strtolower($name);
            }
            
if (array_key_exists($name, $this->_options)) {
                
// This is a Core option
                $this->_setOption($name, $value);
                
return;
            }
            
if (array_key_exists($name, $this->_specificOptions)) {
                
// This a specic option of this frontend
                $this->_specificOptions[$name= $value;
                
return;
            }
        }
        Zend_Cache
::throwException("Incorrect option name : $name");
    }

    
/**
     * Set an option
     *
     * @param string $name name of the option
     * @param mixed $value value of the option
     
*/
    
private function _setOption($name, $value)
    {
        
if (!is_string($name|| !array_key_exists($name, $this->_options)) {
            Zend_Cache
::throwException("Incorrect option name : $name");
        }
        
$this->_options[$name= $value;
    }

    
/**
     * Force a new lifetime
     * 设置缓存的生命期
     * The new value is set for the core/frontend but for the backend too (directive)
     *
     * @param int $newLifetime new lifetime (in seconds)
     
*/
    
public function setLifetime($newLifetime)
    {
        
$this->_options['lifetime'= $newLifetime;
        
$this->_backend->setDirectives(array(
            
'lifetime' => $newLifetime
        ));
    }

    
/**
     * Test if a cache is available for the given id and (if yes) return it (false else)
     * 加载缓存 返回内容
     * @param string $id cache id
     * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
     * @param boolean $doNotUnserialize do not serialize (even if automatic_serialization is true) => for internal use
     * @return mixed cached datas (or false)
     
*/
    
public function load($id, $doNotTestCacheValidity = false, $doNotUnserialize = false)
    {
        
if (!$this->_options['caching']) {
            
return false;
        }
        
$this->_lastId = $id;    //保存为最后一次使用的缓冲
        self::_validateIdOrTag($id);
        
$data = $this->_backend->load($id, $doNotTestCacheValidity);    //采用后端模块加载缓存 得到被缓存的内容
        if ($data===false) {
            
// no cache available
            return false;
        }
        
if ((!$doNotUnserialize&& $this->_options['automatic_serialization']) {
            
// we need to unserialize before sending the result
            return unserialize($data);    //到内容进行 反序列化
        }
        
return $data;
    }

    
/**
     * THIS METHOD IS DEPRECATED : USE LOAD() INSTEAD (same syntax) !
     * 为了兼容 早期zf 等同于 load 方法
     * it will be removed in ZF 1.1 !
     
*/
    
public function get($id, $doNotTestCacheValidity = false, $doNotUnserialize = false)
    {
        
$this->_log("get() method is deprecated => use load() method instead (same syntax) !");
        
return $this->load($id, $doNotTestCacheValidity, $doNotUnserialize);
    }

    
/**
     * Test if a cache is available for the given id
     *    通过调用后端模块  检测缓存是否可用 
     * @param string $id cache id
     * @return boolean true is a cache is available, false else
     
*/
    
public function test($id)
    {
        
if (!$this->_options['caching']) {
            
return false;
        }
        self
::_validateIdOrTag($id);
        
$this->_lastId = $id;
        
return $this->_backend->test($id);
    }

    
/**
     * Save some data in a cache 保存数据到缓存
     *
     * @param mixed $data data to put in cache (can be another type than string if automatic_serialization is on)
     *      $data 混合类型 如果不是字符窜类型 必须打开 automatic_serialization 
     * @param cache $id cache id (if not set, the last cache id will be used) 默认采用最后一次使用的缓存id
     * @param array $tags cache tags    标签数组
     * @param int $specificLifetime if != false, set a specific lifetime for this cache record (null => infinite lifetime)
     * @return boolean true if no problem
     
*/
    
public function save($data, $id = null, $tags = array(), $specificLifetime = false)
    {
        
if (!$this->_options['caching']) {    //不进行缓存
            return true;
        }
        
if (is_null($id)) {
            
$id = $this->_lastId;
        }
        self
::_validateIdOrTag($id);
        self
::_validateTagsArray($tags);
        
if ($this->_options['automatic_serialization']) {
            
// we need to serialize datas before storing them
            $data = serialize($data);
        } 
else {
            
if (!is_string($data)) {
                Zend_Cache
::throwException("Datas must be string or set automatic_serialization = true");
            }
        }
        
// automatic cleaning 随机清理过期缓存
        if ($this->_options['automatic_cleaning_factor'> 0) {
            
$rand = rand(1, $this->_options['automatic_cleaning_factor']);
            
if ($rand==1) {
                
if ($this->_backend->isAutomaticCleaningAvailable()) {
                    
$this->clean(Zend_Cache::CLEANING_MODE_OLD);
                } 
else {
                    
$this->_log('Zend_Cache_Core::save() / automatic cleaning is not available with this backend');
                }
            }
        }
        
$result = $this->_backend->save($data, $id, $tags, $specificLifetime);//通过后台模块进行保存缓存
        if (!$result) {
            
// maybe the cache is corrupted, so we remove it !
            if ($this->_options['logging']) {
                
$this->_log("Zend_Cache_Core::save() : impossible to save cache (id=$id)");
            }
            
$this->remove($id);
            
return false;
        }
        
if ($this->_options['write_control']) { //写入时检测与原来的内容是否不一致
            $data2 = $this->_backend->load($id, true);    //得到缓冲内容
            if ($data!=$data2) {    //内容不一样了 
                $this->_log('Zend_Cache_Core::save() / write_control : written and read data do not match');
                
$this->remove($id);    //删除当前缓存 
                return false;
            }
        }
        
return true;
    }

    
/**
     * Remove a cache
     * 调用后端模块 删除指定id的缓存
     * @param string $id cache id to remove
     * @return boolean true if ok
     
*/
    
public function remove($id)
    {
        
if (!$this->_options['caching']) {
            
return true;
        }
        self
::_validateIdOrTag($id);
        
return $this->_backend->remove($id);
    }

    
/**
     * Clean cache entries
     * 调用后端模块 清除指定类型的缓存
     * Available modes are :
     * 'all' (default)  => remove all cache entries ($tags is not used)
     * 'old'            => remove too old cache entries ($tags is not used)
     * 'matchingTag'    => remove cache entries matching all given tags
     *                     ($tags can be an array of strings or a single string)
     * 'notMatchingTag' => remove cache entries not matching one of the given tags
     *                     ($tags can be an array of strings or a single string)
     *
     * @param string $mode
     * @param mixed $parameters
     * @return boolean true if ok
     
*/
    
public function clean($mode = 'all', $tags = array())
    {
        
if (!$this->_options['caching']) {
            
return true;
        }
        
if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL, Zend_Cache::CLEANING_MODE_OLD, Zend_Cache::CLEANING_MODE_MATCHING_TAG, Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG))) {
            Zend_Cache
::throwException('Invalid cleaning mode');
        }
        self
::_validateTagsArray($tags);
        
return $this->_backend->clean($mode, $tags);
    }

    
// ------------------------------------
    // --- Private or protected methods ---
    // ------------------------------------


    
/**
     * Validate a cache id or a tag (security, reliable filenames, reserved prefixes...)
     * 检查缓存id格式 是否合法
     * 
     * Throw an exception if a problem is found
     *
     * @param string $string cache id or tag
     
*/
    
private static function _validateIdOrTag($string)
    {
        
if (!is_string($string)) {    //缓存id必须是字符窜
            Zend_Cache::throwException('Invalid id or tag : must be a string');
        }
        
if (substr($string, 0, 9== 'internal-') { //是保留的关键字
            Zend_Cache::throwException('"internal-*" ids or tags are reserved');
        }
        
if (!preg_match('~^[w]+$~', $string)) { //使用了非法字符
            Zend_Cache::throwException('Invalid id or tag : must use only [a-zA-Z0-9_]');
        }
    }

    
/**
     * Validate a tags array (security, reliable filenames, reserved prefixes...)
     *  检查缓存id数组 格式 是否合法
     * Throw an exception if a problem is found
     *
     * @param array $tags array of tags
     
*/
    
private static function _validateTagsArray($tags)
    {
        
if (!is_array($tags)) {
            Zend_Cache
::throwException('Invalid tags array : must be an array');
        }
        
foreach($tags as $tag) {
            self
::_validateIdOrTag($tag);
        }
        
reset($tags);
    }

    
/**
     * Make sure if we enable logging that the Zend_Log class
     * is available.
     * Create a default log object if none is set.
     * 建立日志模块
     * @return void
     * @throws Zend_Cache_Exception
     
*/
    
protected function _loggerSanity()
    {
        
if (!isset($this->_options['logging']) || !$this->_options['logging']) {
            
return;
        }
        
try {
            
require_once 'Zend/Loader.php';
            Zend_Loader
::loadClass('Zend_Log');
        } 
catch (Zend_Exception $e) {
            Zend_Cache
::throwException('Logging feature is enabled but the Zend_Log class is not available');
        }
        
if (isset($this->_options['logger']) && $this->_options['logger'] instanceof Zend_Log) {
            
return;
        }
        
// Create a default logger to the standard output stream
        Zend_Loader::loadClass('Zend_Log_Writer_Stream');
        
$logger = new Zend_Log(new Zend_Log_Writer_Stream('php://output'));
        
$this->_options['logger'= $logger;
    }

    
/**
     * Log a message at the WARN (4) priority.
     * 记录日志
     * @param string $message
     * @return void
     * @throws Zend_Cache_Exception
     
*/
    
protected function _log($message, $priority = 4)
    {
        
if (!$this->_options['logging']) {
            
return;
        }
        
if (!(isset($this->_options['logger']) || $this->_options['logger'] instanceof Zend_Log)) {
            Zend_Cache
::throwException('Logging is enabled but logger is not set');
        }
        
$logger = $this->_options['logger'];
        
$logger->log($message, $priority);
    }

}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值