Swoole单例模式及依赖注入进行Redis底层类库封装

作者 : 开心源码 本文共6556个字,预计阅读时间需要17分钟 发布时间: 2022-05-13 共167人阅读
  1. redis安装及php-redis扩展安装
  2. 初步使用
  3. 封装基类 – 单例模式
  4. 优化封装 – 依赖注入
  5. 从配置加载
  6. 从自己设置配置加载
    本文将一步一步的从redis的安装一直到easySwoole使用高度封装的底层类库,并进行优化提高代码的维护性,可以直接看最后的优化结果

第一部分 redis安装及php-redis扩展安装

redis的安装很简单,直接到redis官网下载,这里使用的是redis4.0.12,下载后直接make && make install就可,
进入到redis的文件夹的src目录,运行一个redis服务,其默认端口是6379:

./redis-server

运行一个redis用户端

./redis-cli

安装php-redis也很简单,从github把扩展下载下来解压,而后

phpize./configuremake && make install

就可,假如想要configure到指定的php版本就指定phpize的目录并在config的时候prefix到指定的php配置文件,安好之后再php.ini加上redis.so就可。

第二部分 初步使用

直接在源码中进行redis的连接:

<?php/** * Created by bingxiong. * Date: 12/19/18 * Time: 6:38 PM * Description: */ namespace App\HttpController\Api; use \EasySwoole\Core\Component\Di;// 使用封装的redis基类use App\Lib\Redis\Redis; class Index extends Base{    public function getRedis(){        $redis = new \Redis();        $redis->connect("127.0.0.1",6379, 5);        $redis->set("bing",19249);        return $this->writeJson(200,'OK',$redis->get("bing"));    } }

显然我们不可能这样使用,需要对其进行二次封装

第三部分 创立Redis的基类

基类创立在App->Lib->Redis->redis.php

<?php/** * Created by bingxiong. * Date: 12/21/18 * Time: 12:44 AM * Description: */ namespace App\Lib\Redis; // 使用单例模式use EasySwoole\Config;use EasySwoole\Core\AbstractInterface\Singleton; class Redis{    use Singleton;     public $redis = "";     private function __construct()    {        //判断扩展有没有安装        if(!extension_loaded('redis')){            throw new \Exception("redis.so文件不存在");        }        try{            $this->redis = new \Redis();            $result = $this->redis->connect("127.0.0.1",6379,3);        } catch (\Exception $e){            throw new \Exception("redis服务异常");        }         if($result === false){            throw new \Exception("redis连接失败");        }    }     /**     * 重写get友好的返回key不存在的情况     * @param $key     * @return bool|string     */    public function get($key){        if(empty($key)){            return '';        }        return $this->redis->get($key);    } }

说明:
使用了单例模式:用于为一个类生成一个唯一的对象。最常用的地方是数据库连接。 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。作为对象的创立模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。1、一个类只能有一个实例 2、它必需自行创立这个实例 3、它必需自行向整个系统提供这个实例
有了基类之后,配置和连接的任务就从基类的构造函数加载了,之前的代码就变成了

<?php/** * Created by bingxiong. * Date: 12/19/18 * Time: 6:38 PM * Description: */ namespace App\HttpController\Api;  use \EasySwoole\Core\Component\Di;// 使用封装的redis基类use App\Lib\Redis\Redis; class Index extends Base{     public function getRedis(){        $result = Redis::getInstance()->get('bing');        return $this->writeJson(200,'OK',$result);    } }

第四部分 依赖注入

依赖注入:一个对象提供另一个对象的依赖关系,是一种设计模式,好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
easyswool使用依赖注入非常的简单,在easyswoolevent的文件中

public static function mainServerCreate(ServerManager $server,EventRegister $register): void    {        Di::getInstance()->set('MYSQL',\MysqliDb::class,Array (                'host' => '127.0.0.1',                'username' => 'root',                'password' => 'root',                'db'=> 'imooc_video',                'port' => 8889,                'charset' => 'utf8')        );        Di::getInstance()->set('REDIS',Redis::getInstance());     }

上面的是我数据库的配置,下面getInstance中实例化了刚才封装的基类

实例化di再getInstance即可以了

<?php/** * Created by bingxiong. * Date: 12/19/18 * Time: 6:38 PM * Description: */ namespace App\HttpController\Api;  use \EasySwoole\Core\Component\Di;// 使用封装的redis基类use App\Lib\Redis\Redis; class Index extends Base{     public function getRedis(){        // 3使用依赖注入        $result = Di::getInstance()->get('REDIS')->get('bing');        return $this->writeJson(200,'OK',$result);    } }

第5部分 从配置加载

在配置文件中增加,或者者用你喜欢的方式配置

'REDIS' => [     'host' => '127.0.0.1',     'port' => 6379,     'time_out' => 3 ]

而后基类改写成

<?php/** * Created by bingxiong. * Date: 12/21/18 * Time: 12:44 AM * Description: */ namespace App\Lib\Redis; // 使用单例模式use EasySwoole\Config;use EasySwoole\Core\AbstractInterface\Singleton; class Redis{    use Singleton;     public $redis = "";     private function __construct()    {        //判断扩展有没有安装        if(!extension_loaded('redis')){            throw new \Exception("redis.so文件不存在");        }        try{            //从配置加载REDIS - 提高维护性            $redisConfig = Config::getInstance()->getConf("REDIS");            $this->redis = new \Redis();            $result = $this->redis->connect($redisConfig['host'],$redisConfig['port'],$redisConfig['time_out']);        } catch (\Exception $e){            throw new \Exception("redis服务异常");        }         if($result === false){            throw new \Exception("redis连接失败");        }    }     /**     * 重写get友好的返回key不存在的情况     * @param $key     * @return bool|string     */    public function get($key){        if(empty($key)){            return '';        }        return $this->redis->get($key);    } }

第6部分 从自己设置配置加载

因为可能有很多配置,把配置都放在这个文件的话会显得很臃肿,因而我们将每个配置文件比方redis mysql elasticsearch的配置单独抽离出来单独管理,这样有更好的维护性

所以在根目录创立config->redis.php,在这里直接返回redis的配置

<?php/** * Created by bingxiong. * Date: 12/21/18 * Time: 2:10 AM * Description: redis相关配置 */ return ['host' => '127.0.0.1', 'port' => 6379, 'time_out' => 3];

而后自己设置载入配置文件,创立了一个loadConf方法,这个方法在easyswoole的文档中有,所以最终的

EasySwooleEvent.php

<?php/** * Created by PhpStorm. * User: yf * Date: 2018/1/9 * Time: 下午1:04 */ namespace EasySwoole; use App\Lib\Redis\Redis;use \EasySwoole\Core\AbstractInterface\EventInterface;use EasySwoole\Core\Component\Di;use \EasySwoole\Core\Swoole\ServerManager;use \EasySwoole\Core\Swoole\EventRegister;use \EasySwoole\Core\Http\Request;use \EasySwoole\Core\Http\Response;use \EasySwoole\Core\Utility\File; Class EasySwooleEvent implements EventInterface {     public static function frameInitialize(): void    {        // TODO: Implement frameInitialize() method.        date_default_timezone_set('Asia/Shanghai');        self::loadConf(EASYSWOOLE_ROOT.'/Config');    }     public static function loadConf($ConfPath)    {        $Conf  = Config::getInstance();        $files = File::scanDir($ConfPath);        foreach ($files as $file) {            $data = require_once $file;            $Conf->setConf(strtolower(basename($file, '.php')), (array)$data);        }    }     /**     * 使用依赖注入加载     * @param ServerManager $server     * @param EventRegister $register     */    public static function mainServerCreate(ServerManager $server,EventRegister $register): void    {        Di::getInstance()->set('MYSQL',\MysqliDb::class,Array (                'host' => '127.0.0.1',                'username' => 'root',                'password' => 'root',                'db'=> 'imooc_video',                'port' => 8889,                'charset' => 'utf8')        );        Di::getInstance()->set('REDIS',Redis::getInstance());     }     public static function onRequest(Request $request,Response $response): void    {        // TODO: Implement onRequest() method.    }     public static function afterAction(Request $request,Response $response): void    {        // TODO: Implement afterAction() method.    }}

redis.php 这是redis的基类
<?php
/**

  • Created by bingxiong.
  • Date: 12/21/18
  • Time: 12:44 AM
  • Description:
    */

namespace App\Lib\Redis;

// 使用单例模式
use EasySwoole\Config;
use EasySwoole\Core\AbstractInterface\Singleton;

class Redis
{
use Singleton;

public $redis = "";private function __construct(){    //判断扩展有没有安装    if(!extension_loaded('redis')){        throw new \Exception("redis.so文件不存在");    }    try{        // 从自己的配置加载        $redisConfig = Config::getInstance()->getConf("redis");        $this->redis = new \Redis();        $result = $this->redis->connect($redisConfig['host'],$redisConfig['port'],$redisConfig['time_out']);    } catch (\Exception $e){        throw new \Exception("redis服务异常");    }    if($result === false){        throw new \Exception("redis连接失败");    }}/** * 重写get友好的返回key不存在的情况 * @param $key * @return bool|string */public function get($key){    if(empty($key)){        return '';    }    return $this->redis->get($key);}

}
最终实现

/** * Created by bingxiong. * Date: 12/19/18 * Time: 6:38 PM * Description: */ namespace App\HttpController\Api; use \EasySwoole\Core\Component\Di; class Index extends Base{    public function getRedis(){        // 使用依赖注入        $result = Di::getInstance()->get('REDIS')->get('bing');        return $this->writeJson(200,'OK',$result);    } }

本人文章均为原创,个人网站Bing的天涯路,转载请注明出处。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Swoole单例模式及依赖注入进行Redis底层类库封装

发表回复