高效PHP Redis缓存技巧,可参考下步骤
能否想过PHP应用redis作为缓存时,若何能:
● 先后台模块共用Model层;
● 然而,不克不及每一个Model类都进行缓存,这样太糜费Redis资本;
● 先后台模块能够自在决议从数据库仍是从缓存读数据;
● 不冗余代码;
● 应用不便。
● 这里咱们先展现完成的终极成果。
终极的代码以及应用阐明请移步Github:
https://github.com/yeszao/php-redis-cache。
即刻装置应用饬令:
$ composer install yeszao/cache
通过简略设置装备摆设就能够应用,请参看Github的README阐明。
1 终极成果
假定正在MVC框架中,model层有一个Book类以及一个getById办法,以下:
class Book { public function getById($id) { return $id; } }
退出缓存技巧之后,原来办法的挪用形式以及前往的数据构造都不该该扭转。
以是,咱们心愿,最初的成果应该是这样的:
(new Book)->getById(100); // 原始的、不必缓存的挪用形式,仍是原来的形式,普通是读取数据库的数据。 (new Book)->getByIdCache(100); // 应用缓存的挪用形式,缓存键名为:app_models_book:getbyid: + md5(参数列表) (new Book)->getByIdClear(100); // 删除了这个缓存 (new Book)->getByIdFlush(); // 删除了 getById() 办法对应的一切缓存,即删除了 app_models_book:getbyid:*。这个办法没有需求参数。
这样咱们能够很分明的明确本人正在做甚么,同时又晓得数据的起源函数,而且被援用形式齐全对立,堪称一箭三雕。
其实完成起来也比拟简略,就是应用PHP的魔术办法__call()办法。
2 __call()办法
这里简略阐明一下__call办法的作用。
正在PHP中,当咱们拜访一个没有存正在的类办法时,就会挪用这个类的__call()办法。
(假如类办法没有存正在,又不写__call()办法,PHP会间接报错)
假定咱们有一个Book类:
class Book { public function __call($name, $arguments) { echo '类Book没有存正在办法', $name, PHP_EOL; } public function getById($id) { echo '我的ID是', $id, PHP_EOL; } }
当挪用存正在的getById(50)办法时,顺序打印:我的ID是50。
而假如挪用没有存正在的getAge()办法时,顺序就会执行到A类的__call()办法外面,这里会打印:类Book没有存正在办法getAge。
这就是__call的原理。
3 完成细节
接上去咱们就行使__call()办法的这类特点,来完成缓存战略。
从下面的例子,咱们看到,__call()办法被挪用时,会传入两个参数。
name:想要挪用的办法名arguments:参数列表
咱们就能够正在参数下面做文章。
仍是以Book类为例,咱们假定其本来构造以下:
class Book { public function __call($name, $arguments) { // 待填充内容 } public function getById($id) { return ['id' => $id, 'title' => 'PHP缓存技巧' . $id]; } }
开端以前,咱们还确认Redis的衔接,这是缓存必需用到的,这里咱们写个简略的单例类:
class Co妹妹on { private static $redis = null; public static function redis() { if (self::$redis === null) { self::$redis = new \Redis('127.0.0.1'); self::$redis->connect('redis'); } return self::$redis; }
而后,咱们开端填充__call()办法代码,详细阐明请看正文:
class Book { public function __call($name, $arguments) { // 由于咱们次要是依据办法名的后缀决议详细操作, // 以是假如传入的 $name 长度小于5,能够间接报错 if (strlen($name) < 5) { exit('Method does not exist.'); } // 接着,咱们截取 $name,猎取原办法以及要执行的举措, // 是cache、clear仍是flush,这里咱们取了个巧,举措 // 的称号都是5个字符,这样截取就十分高效。 $method = substr($name, 0, -5); $action = substr($name, -5); // 以后挪用的类称号,包罗定名空间的称号 $class = get_class(); // 天生缓存键名,$arguments稍后再加之 $key = sprintf('%s:%s:', str_replace('\\', '_', $class), $method); // 都用小写难看点 $key = strtolower($key); switch ($action) { case 'Cache': // 缓存键名加之$arguments $key = $key . md5(json_encode($arguments)); // 从Redis中读取数据 $data = Co妹妹on::redis()->get($key); // 假如Redis中无数据 if ($data !== false) { $decodeData = json_decode($data, JSON_UNESCAPED_UNICODE); // 假如没有是JSON格局的数据,间接前往,不然前往json解析后的数据 return $decodeData === null ? $data : $decodeData; } // 假如Redis中不数据则持续往下执行 // 假如原办法没有存正在 if (method_exists($this, $method) === false) { exit('Method does not exist.'); } // 挪用原办法猎取数据 $data = call_user_func_array([$this, $method], $arguments); // 保留数据到Redis中以便下次应用 Co妹妹on::redis()->set($key, json_encode($data), 3600); // 完结执行并前往数据 return $data; break; case 'Clear': // 缓存键名加之$arguments $key = $key . md5(json_encode($arguments)); return Co妹妹on::redis()->del($key); break; case 'Flush': $key = $key . '*'; // 猎取一切合乎 $class:$method:* 规定的缓存键名 $keys = Co妹妹on::redis()->keys($key); return Co妹妹on::redis()->del($keys); break; default: exit('Method does not exist.'); } } // 其余办法 }
这样就完成了咱们开端时的成果。
4 实际应用时
正在实际应用中,咱们需求做一些扭转,把这一段代码纳入一个类中,
而后正在model层的基类中援用这个类,再传入Redis句柄、类工具、办法名以及参数,
这样能够升高代码的耦合,应用起来也更灵敏。
完好的代码曾经放正在Github上,请参考文章扫尾的参考地点。
更多相干php常识,请拜访php教程!
以上就是PHP应用redis作为缓存(高效技巧)的具体内容,更多请存眷资源魔其它相干文章!
标签: php php开发教程 php开发资料 php开发自学
抱歉,评论功能暂时关闭!