构建自己的PHP框架--构建缓存组件(1)
作為一個框架,我們還沒有相應的緩存組件,下面我們就來構建我們的緩存組件。
先來定義一下接口,在 src 文件夾下創建 cache 文件夾,在cache文件夾下創建 CacheInterface.php 文件,其中定義 Cache 相應的接口,其內容如下:
<?php
namespace sf\cache;/*** CacheInterface* @author Harry Sun <sunguangjun@126.com>*/
interface CacheInterface
{/*** Builds a normalized cache key from a given key.*/public function buildKey($key);/*** Retrieves a value from cache with a specified key.*/public function get($key);/*** Checks whether a specified key exists in the cache.*/public function exists($key);/*** Retrieves multiple values from cache with the specified keys.*/public function mget($keys);/*** Stores a value identified by a key into cache.*/public function set($key, $value, $duration = 0);/*** Stores multiple items in cache. Each item contains a value identified by a key.*/public function mset($items, $duration = 0);/*** Stores a value identified by a key into cache if the cache does not contain this key.* Nothing will be done if the cache already contains the key.*/public function add($key, $value, $duration = 0);/*** Stores multiple items in cache. Each item contains a value identified by a key.* If the cache already contains such a key, the existing value and expiration time will be preserved.*/public function madd($items, $duration = 0);/*** Deletes a value with the specified key from cache*/public function delete($key);/*** Deletes all values from cache.*/public function flush();
} 定義了 buildKey/get/mget/set/mset/exists/add/madd/delete/flush接口,對應功能如下:
- buildKey:構建真正的 key,避免特殊字符影響實現
- get:根據 key 獲取緩存的值
- mget:根據 keys 數組獲取多個緩存值
- set:根據 key 設置緩存的值
- mset:根據數組設置多個緩存值
- exists:判斷 key 是否存在
- add:如果 key 不存在就設置緩存值,否則返回false
- madd:根據數組,判斷相應的 key 不存在就設置緩存值
- delete:根據 key 刪除一個緩存
- flush:刪除所有的緩存
實現緩存,可以使用很多方式,比如使用文件、數據庫、memcache 以及 Redis 等。
我們今天先使用文件緩存來實現相應的接口。
其主要思想就是,每一個 key 都對應一個文件,緩存的內容序列化一下,存入到文件中,取出時再反序列化一下。剩下的基本都是相應的文件操作了。
在 src/cache 文件夾下創建 FileCache.php 文件,其內容如下:
<?php
namespace sf\cache;/*** CacheInterface* @author Harry Sun <sunguangjun@126.com>*/
class FileCache implements CacheInterface
{/*** @var string the directory to store cache files.* 緩存文件的地址,例如/Users/jun/projects/www/simple-framework/runtime/cache/*/public $cachePath;/*** Builds a normalized cache key from a given key.*/public function buildKey($key){if (!is_string($key)) {// 不是字符串就json_encode一把,轉成字符串,也可以用其他方法$key = json_encode($key);}return md5($key);}/*** Retrieves a value from cache with a specified key.*/public function get($key){$key = $this->buildKey($key);$cacheFile = $this->cachePath . $key;// filemtime用來獲取文件的修改時間if (@filemtime($cacheFile) > time()) {// file_get_contents用來獲取文件內容,unserialize用來反序列化文件內容return unserialize(@file_get_contents($cacheFile));} else {return false;}}/*** Checks whether a specified key exists in the cache.*/public function exists($key){$key = $this->buildKey($key);$cacheFile = $this->cachePath . $key;// 用修改時間標記過期時間,存入時會做相應的處理return @filemtime($cacheFile) > time();}/*** Retrieves multiple values from cache with the specified keys.*/public function mget($keys){$results = [];foreach ($keys as $key) {$results[$key] = $this->get($key);}return $results;}/*** Stores a value identified by a key into cache.*/public function set($key, $value, $duration = 0){$key = $this->buildKey($key);$cacheFile = $this->cachePath . $key;// serialize用來序列化緩存內容$value = serialize($value);// file_put_contents用來將序列化之后的內容寫入文件,LOCK_EX表示寫入時會對文件加鎖if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) {if ($duration <= 0) {// 不設置過期時間,設置為一年,這是因為用文件的修改時間來做過期時間造成的// redis/memcache 等都不會有這個問題$duration = 31536000; // 1 year}// touch用來設置修改時間,過期時間為當前時間加上$durationreturn touch($cacheFile, $duration + time());} else {return false;}}/*** Stores multiple items in cache. Each item contains a value identified by a key.*/public function mset($items, $duration = 0){$failedKeys = [];foreach ($items as $key => $value) {if ($this->set($key, $value, $duration) === false) {$failedKeys[] = $key;}}return $failedKeys;}/*** Stores a value identified by a key into cache if the cache does not contain this key.*/public function add($key, $value, $duration = 0){// key不存在,就設置緩存if (!$this->exists($key)) {return $this->set($key, $value, $duration);} else {return false;}}/*** Stores multiple items in cache. Each item contains a value identified by a key.*/public function madd($items, $duration = 0){$failedKeys = [];foreach ($items as $key => $value) {if ($this->add($key, $value, $duration) === false) {$failedKeys[] = $key;}}return $failedKeys;}/*** Deletes a value with the specified key from cache*/public function delete($key){$key = $this->buildKey($key);$cacheFile = $this->cachePath . $key;// unlink用來刪除文件return unlink($cacheFile);}/*** Deletes all values from cache.* Be careful of performing this operation if the cache is shared among multiple applications.* @return boolean whether the flush operation was successful.*/public function flush(){// 打開cache文件所在目錄$dir = @dir($this->cachePath);// 列出目錄中的所有文件while (($file = $dir->read()) !== false) {if ($file !== '.' && $file !== '..') {unlink($this->cachePath . $file);}}// 關閉目錄$dir->close();}
} 相關實現的解釋都直接寫在code中的注釋里了。
然后我們來測試一下我們的緩存組件,首先我們需要添加一下配置文件,在 config 文件夾下創建 cache.php 文件,配置如下內容:
<?php
return ['class' => '\sf\cache\FileCache','cachePath' => SF_PATH . '/runtime/cache/'
]; 然后在 SiteController.php 中簡單使用如下:
public function actionCache(){$cache = Sf::createObject('cache');$cache->set('test', '我就是測試一下緩存組件');$result = $cache->get('test');$cache->flush();echo $result;} 訪問 http://localhost/simple-framework/public/index.php?r=site/cache 路徑,得到結果如下:
我就是測試一下緩存組件 這樣我們完成了使用文件的緩存組件。
好了,今天就先到這里。項目內容和博客內容也都會放到Github上,歡迎大家提建議。
code:https://github.com/CraryPrimitiveMan/simple-framework/tree/0.9
blog project:https://github.com/CraryPrimitiveMan/create-your-own-php-framework
轉載于:https://www.cnblogs.com/CraryPrimitiveMan/p/5428224.html
總結
以上是生活随笔為你收集整理的构建自己的PHP框架--构建缓存组件(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经典二战电影,真实的,好看的
- 下一篇: 集合、函数