Redis是一个key-value存储系统。有多种存储类型string(字符串)、list(链表)、set(集合)、zset(有序集合)和hash(哈希类型)。也就意味着学习成本会比其他非关系型数据库的学习成本高.27.jpgRedis为了保证效率,数据都是缓存在内存中。并且Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步.

  Redis数据库和其他的一样每次使用都需要发起一个链接请求.但是在多次使用的时候会出现重复链接,会对资源造成很大的浪费.这里就直接使用单例模式.防止多次使用而进行多次链接浪费资源的情况

  看一下源码中vendor\easyswoole\component\src\Singleton.php文件

namespace EasySwoole\Component;


trait Singleton
{
    private static $instance;

    static function getInstance(...$args)
    {
        if(!isset(self::$instance)){
            self::$instance = new static(...$args);
        }
        return self::$instance;
    }
}

  这里的trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类.注意是可以做类.但trait不是类,所以不能有静态成员,类常量,当然也不可能被实例化。使用的时候直接use就好了.这方面不懂的可以百度了解一下哈~
  在EasySwoole的App目录下创建一个用于存放基础类库的Lib文件夹.并且在该目录下创建创建Redis/Redis.php文件
我们刚才看到trait Singleton中用的是单例模式.我们直接使用就行.不用再自己编写了.

namespace App\Lib\Redis;

use EasySwoole\Component\Singleton;
use EasySwoole\EasySwoole\Config;
use \Yaconf;

class Redis
{
    use Singleton;
}

  我们这里的use Singleton;就相当于把刚才在vendor\easyswoole\component\src\Singleton.php看到的的代码拿到了我们的redis中使用了.
使用__construct魔术方法下编写Redis链接对相关逻辑

public $redis = null;

private function __construct()
{
    /*判断有没有安装redis拓展*/
    if (!extension_loaded('redis')) {
        throw new \Exception('redis拓展不存在');
    }
    try {
        $this->redis = new \Redis();
        $link = $this->redis->connect(Yaconf::get('redis.host'), Yaconf::get('redis.port'), Yaconf::get('redis.time_out'));
    } catch (\Exception $e) {
        /*
         * 因为$e->getmaessage会把详细信息输入上去
         * 这些数据是比较隐蔽的。我们不能让别人看到
         * throw new \Exception($e->getMessage());
        */
        throw new \Exception('redis服务异常');
    }
    if (!$link) {
        throw new \Exception('redis链接失败');
    }
}

php中使用Redisi和直接使用Redis掉的方法名是差不多的.为了使代码更优雅,我们这里直接使用__call魔术方法

public function __call($name, $arguments)
{
    $count = count($arguments);
    if ($count == 1) {
        return $this->redis->$name($arguments[0]);
    } elseif ($count == 2) {
        return $this->redis->$name($arguments[0], $arguments[1]);
    } elseif ($count == 3) {
        return $this->redis->$name($arguments[0], $arguments[1], $arguments[2]);
    }
    return '';
}

如果我们在Model曾中这样调用

Redis::getInstance()->setEx('qvbilam',10,'hello');

因为setEx方法不存在所以会走到__call($name,$arguments).而

$name = 'setEx';
$arguments = ['qvbilam',10,'hello'];
//因为count($argument=3)
return $this->redis->setEx('qvbilam',10,'hello');

就自动创建了一个10秒过期健名为qvbilam值为hello字符串.
image.png
测试成功.非常棒了~加油
16.gif

Last modification:February 6th, 2020 at 01:35 pm