bet亚洲官方网站-bet3365娱乐场手机版

自定义缓存实现

Smarty默认是使用基于文件的缓存机制,作为可选的方案,你可以自定义一套缓存机制的实现,来进行缓存文件的读写和删除。

Note

Smarty2使用$cache_handler_func的回调函数来实现此功能。 而Smarty3使用了Smarty_CacheResource模块来实现。

自定义缓存实现可以实现类似下面的目的: 用更快的存储引擎来替代较慢的文件系统, 使缓存可以分布到多台服务器上。

Smarty可以通过API Smarty_CacheResource_Custom 或者 Smarty_CacheResource_KeyValueStore 来实现缓存机制。 Smarty_CacheResource_Custom是比较简单的API,直接通过覆盖读、写、删除等操作来实现缓存机制。 该API可以使用于任何你觉得适合的方式,或存储到任何你觉得适合的地方。 Smarty_CacheResource_KeyValueStore的API可让你使用K-V存储模式(比如APC,Memcache等)来实现缓存机制。 更进一步,就算是多层的缓存组如"a|b|c",该API也让你可以通过删除缓存组"a"来将整个嵌套的缓存组删除, 即使K-V存储机制本身无法实现这种层次结构的存储。

自定义缓存可以放到$plugins_dir目录下并命名为cacheresource.foobarxyz.php, 或者在运行时通过registerCacheResource() 来进行注册。 上面两种方式都必须设置$caching_type 来启动你的自定义缓存机制。

Example 15.15. 通过MySQL实现自定义缓存机制


<?php

require_once libs/Smarty.class.php;
$smarty = new Smarty();
$smarty->caching_type = mysql;

/**
 * MySQL 缓存
 *
 * 通过自定义缓存的接口API,让MySQL来作为Smarty的输出缓存存储器。
 *
 * 表定义:
 * <pre>CREATE TABLE IF NOT EXISTS `output_cache` (
 *   `id` CHAR(40) NOT NULL COMMENT sha1 hash,
 *   `name` VARCHAR(250) NOT NULL,
 *   `cache_id` VARCHAR(250) NULL DEFAULT NULL,
 *   `compile_id` VARCHAR(250) NULL DEFAULT NULL,
 *   `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
 *   `content` LONGTEXT NOT NULL,
 *   PRIMARY KEY (`id`),
 *   INDEX(`name`),
 *   INDEX(`cache_id`),
 *   INDEX(`compile_id`),
 *   INDEX(`modified`)
 * ) ENGINE = InnoDB;</pre>
 *
 * @package CacheResource-examples
 * @author Rodney Rehm
 */
class Smarty_CacheResource_Mysql extends Smarty_CacheResource_Custom {
    // PDO 对象
    protected $db;
    protected $fetch;
    protected $fetchTimestamp;
    protected $save;
    
    public function __construct() {
        try {
            $this->db = new PDO("mysql:dbname=test;host=127.0.0.1", "smarty", "smarty");
        } catch (PDOException $e) {
            throw new SmartyException(Mysql 源无法链接:  . $e->getMessage());
        }
        $this->fetch = $this->db->prepare(SELECT modified, content FROM output_cache WHERE id = :id);
        $this->fetchTimestamp = $this->db->prepare(SELECT modified FROM output_cache WHERE id = :id);
        $this->save = $this->db->prepare(REPLACE INTO output_cache (id, name, cache_id, compile_id, content)
            VALUES  (:id, :name, :cache_id, :compile_id, :content));
    }

    /**
	 * 从数据表中获取缓存的内容及修改时间
     *
     * @param string $id 缓存内容的唯一识别ID
     * @param string $name 模板名称
     * @param string $cache_id 缓存ID
     * @param string $compile_id 编译ID
     * @param string $content (引用的)缓存内容
     * @param integer $mtime 缓存修改的时间戳 (epoch)
     * @return void
     */
    protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime)
    {
        $this->fetch->execute(array(id => $id));
        $row = $this->fetch->fetch();
        $this->fetch->closeCursor();        
        if ($row) {
            $content = $row[content];
            $mtime = strtotime($row[modified]);
        } else {
            $content = null;
            $mtime = null;
        }
    }
    
    /**
	 * 从数据表中获取缓存的修改时间
     *
     * @note 这是个可选的实现接口。在你确定仅获取修改时间会比获取整个内容要更快的时候,使用此接口。
     * @param string $id 缓存内容的唯一识别ID
     * @param string $name 模板名称
     * @param string $cache_id 缓存ID
     * @param string $compile_id 编译ID
     * @return integer|boolean 返回模板修改时间,如果找不到缓存则返回false
     */
    protected function fetchTimestamp($id, $name, $cache_id, $compile_id)
    {
        $this->fetchTimestamp->execute(array(id => $id));
        $mtime = strtotime($this->fetchTimestamp->fetchColumn());
        $this->fetchTimestamp->closeCursor();
        return $mtime;
    }
    
    /**
     * 保存缓存内容到数据表
     *
     * @param string $id 缓存内容的唯一识别ID
     * @param string $name 模板名称
     * @param string $cache_id 缓存ID
     * @param string $compile_id 编译ID
     * @param integer|null $exp_time 缓存过期时间,或null
     * @param string $content 需要缓存的内容
     * @return boolean 成功true,失败false
     */
    protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content)
    {
        $this->save->execute(array(
            id => $id,
            name => $name,
            cache_id => $cache_id,
            compile_id => $compile_id,
            content => $content,
        ));
        return !!$this->save->rowCount();
    }
    
    /**
     * 从数据表中删除缓存
     *
     * @param string $name 模板名称
     * @param string $cache_id 缓存ID
     * @param string $compile_id 编译ID
     * @param integer|null $exp_time 缓存过期时间,或null
     * @return integer 返回被删除的缓存数量
     */
    protected function delete($name, $cache_id, $compile_id, $exp_time)
    {
        // 删除整个缓存
        if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) {
			// 返回删除缓存记录的数量,需要再进行一次查询来计算。
            $query = $this->db->query(TRUNCATE TABLE output_cache);
            return -1;
        }
        // 组成查找条件
        $where = array();
        // 匹配名称
        if ($name !== null) {
            $where[] = name =  . $this->db->quote($name);
        }
        // 匹配编译ID
        if ($compile_id !== null) {
            $where[] = compile_id =  . $this->db->quote($compile_id);
        }
        // 匹配过期时间范围
        if ($exp_time !== null) {
            $where[] = modified < DATE_SUB(NOW(), INTERVAL  . intval($exp_time) .  SECOND);
        }
        // 匹配缓存ID和缓存组的子ID
        if ($cache_id !== null) {
            $where[] = (cache_id = . $this->db->quote($cache_id)
                .  OR cache_id LIKE . $this->db->quote($cache_id .|%) .);
        }
        // 实行删除
        $query = $this->db->query(DELETE FROM output_cache WHERE  . join( AND , $where));
        return $query->rowCount();
    }
}
?>

   

Example 15.16. 通过Memcache实现自定义缓存机制


<?php

require_once libs/Smarty.class.php;
$smarty = new Smarty();
$smarty->caching_type = memcache;

/**
 * Memcache 缓存
 *
 * 通过K-V存储的API来把memcache作为Smarty的输出缓存器。
 *
 * 注意memcache要求key的长度只能是256个字符以内,
 * 所以程序中,key都进行sha1哈希计算后才使用。
 *
 * @package CacheResource-examples
 * @author Rodney Rehm
 */
class Smarty_CacheResource_Memcache extends Smarty_CacheResource_KeyValueStore {
    /**
     * memcache 对象
     * @var Memcache
     */
    protected $memcache = null;
    
    public function __construct()
    {
        $this->memcache = new Memcache();
        $this->memcache->addServer( 127.0.0.1, 11211 );
    }
    
    /**
	 * 从memcache中获取一系列key的值。
     *
     * @param array $keys 多个key
     * @return array 按key的顺序返回的对应值
     * @return boolean 成功返回true,失败返回false
     */
    protected function read(array $keys)
    {
        $_keys = $lookup = array();
        foreach ($keys as $k) {
            $_k = sha1($k);
            $_keys[] = $_k;
            $lookup[$_k] = $k;
        }
        $_res = array();
        $res = $this->memcache->get($_keys);
        foreach ($res as $k => $v) {
            $_res[$lookup[$k]] = $v;
        }
        return $_res;
    }
    
    /**
	 * 将一系列的key对应的值存储到memcache中。
     *
     * @param array $keys 多个kv对应的数据值
     * @param int $expire 过期时间
     * @return boolean 成功返回true,失败返回false
     */
    protected function write(array $keys, $expire=null)
    {
        foreach ($keys as $k => $v) {
            $k = sha1($k);
            $this->memcache->set($k, $v, 0, $expire);
        }
        return true;
    }

    /**
	 * 从memcache中删除
     *
     * @param array $keys 待删除的多个key
     * @return boolean 成功返回true,失败返回false
     */
    protected function delete(array $keys)
    {
        foreach ($keys as $k) {
            $k = sha1($k);
            $this->memcache->delete($k);
        }
        return true;
    }

    /**
     * 清空全部的值
     *
     * @return boolean 成功返回true,失败返回false
     */
    protected function purge()
    {
        return $this->memcache->flush();
    }
}
?>

   

bet亚洲官方网站|bet3365娱乐场手机版

XML 地图 | Sitemap 地图