PHP使用redis作为缓存(高效技术)-php教程

资源魔 28 0

高效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开发自学

抱歉,评论功能暂时关闭!