W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Smarty默認是使用基于文件的緩存機制,作為可選的方案,你可以自定義一套緩存機制的實現(xiàn),來進行緩存文件的讀寫和刪除。
Smarty2使用$cache_handler_func
的回調(diào)函數(shù)來實現(xiàn)此功能。 而Smarty3使用了Smarty_CacheResource
模塊來實現(xiàn)。
自定義緩存實現(xiàn)可以實現(xiàn)類似下面的目的: 用更快的存儲引擎來替代較慢的文件系統(tǒng), 使緩存可以分布到多臺服務(wù)器上。
Smarty可以通過API Smarty_CacheResource_Custom
或者Smarty_CacheResource_KeyValueStore
來實現(xiàn)緩存機制。Smarty_CacheResource_Custom
是比較簡單的API,直接通過覆蓋讀、寫、刪除等操作來實現(xiàn)緩存機制。 該API可以使用于任何你覺得適合的方式,或存儲到任何你覺得適合的地方。Smarty_CacheResource_KeyValueStore
的API可讓你使用K-V存儲模式(比如APC,Memcache等)來實現(xiàn)緩存機制。 更進一步,就算是多層的緩存組如"a|b|c",該API也讓你可以通過刪除緩存組"a"來將整個嵌套的緩存組刪除, 即使K-V存儲機制本身無法實現(xiàn)這種層次結(jié)構(gòu)的存儲。
自定義緩存可以放到$plugins_dir
目錄下并命名為cacheresource.foobarxyz.php
, 或者在運行時通過registerCacheResource()
來進行注冊。 上面兩種方式都必須設(shè)置$caching_type
來啟動你的自定義緩存機制。
Example 15.15. 通過MySQL實現(xiàn)自定義緩存機制
<?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)'); } /** * 從數(shù)據(jù)表中獲取緩存的內(nèi)容及修改時間 * * @param string $id 緩存內(nèi)容的唯一識別ID * @param string $name 模板名稱 * @param string $cache_id 緩存ID * @param string $compile_id 編譯ID * @param string $content (引用的)緩存內(nèi)容 * @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; } } /** * 從數(shù)據(jù)表中獲取緩存的修改時間 * * @note 這是個可選的實現(xiàn)接口。在你確定僅獲取修改時間會比獲取整個內(nèi)容要更快的時候,使用此接口。 * @param string $id 緩存內(nèi)容的唯一識別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; } /** * 保存緩存內(nèi)容到數(shù)據(jù)表 * * @param string $id 緩存內(nèi)容的唯一識別ID * @param string $name 模板名稱 * @param string $cache_id 緩存ID * @param string $compile_id 編譯ID * @param integer|null $exp_time 緩存過期時間,或null * @param string $content 需要緩存的內(nèi)容 * @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(); } /** * 從數(shù)據(jù)表中刪除緩存 * * @param string $name 模板名稱 * @param string $cache_id 緩存ID * @param string $compile_id 編譯ID * @param integer|null $exp_time 緩存過期時間,或null * @return integer 返回被刪除的緩存數(shù)量 */ protected function delete($name, $cache_id, $compile_id, $exp_time) { // 刪除整個緩存 if ($name === null && $cache_id === null && $compile_id === null && $exp_time === null) { // 返回刪除緩存記錄的數(shù)量,需要再進行一次查詢來計算。 $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 .'|%') .')'; } // 執(zhí)行刪除 $query = $this->db->query('DELETE FROM output_cache WHERE ' . join(' AND ', $where)); return $query->rowCount(); } } ?>
Example 15.16. 通過Memcache實現(xiàn)自定義緩存機制
<?php require_once 'libs/Smarty.class.php'; $smarty = new Smarty(); $smarty->caching_type = 'memcache'; /** * Memcache 緩存 * * 通過K-V存儲的API來把memcache作為Smarty的輸出緩存器。 * * 注意memcache要求key的長度只能是256個字符以內(nèi), * 所以程序中,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的順序返回的對應(yīng)值 * @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對應(yīng)的值存儲到memcache中。 * * @param array $keys 多個kv對應(yīng)的數(shù)據(jù)值 * @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(); } } ?>
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: