laravel5.3框架中使用phpredis(自定义Redis服务类)

前言

对于redis的使用,laravel 官方文档建议是用predis,但是因为predis完全是由php来开发的,其性能上与phpredis还是有一定差距的。如果要使用predis的话,参考官方文档,或者查看predis源码即可。

本篇博客主要介绍通过自定义服务类(RedisService)使用phpredis进行redis的相关操作。在RedisService中,除了基本操作外,还写了一些基于phpredis的小工具,比如redis计数器等。

如果要用依赖注入的方式实现RedisService,可以参考这篇博客 《laravel5.3自定义加密服务方案》


项目环境

  • Centos7
  • php7.1
  • nginx1.11

准备工作

php环境部署

具体操作请参考《Centos7安装nginx+php7运行环境》

安装phpredis扩展

具体操作请参考《CenOS7环境安装PHP7扩展》

创建服务类

  • 创建Redis服务类,文件地址 /app/Service/Common/RedisService.php

代码如下:

<?php
/**
 * Redis Service
 * User: Axios
 * Email: axioscros@aliyun.com
 * Date: 2017/1/5
 * Time: 13:50
 */
namespace App\Service\Common;
use \Redis;
class RedisService extends Redis{
    private $config;
    private $prefix;
    private $db;
    public function __construct()
    {
        $this->config = config('database.redis');
        $this->connection();
    }

    /**
     * connect redis
     * @desc 连接redis,外部调用
     * @param string $select  选择redis连接方式
     * @return mixed \Redis|string
     */
    public function connection($select = 'default'){
        if(array_key_exists($select,$this->config)){
            return $this->do_connect($this->config[$select]);
        }else{
            return 'config error';
        }
    }

    /**
     * @desc 进行redis连接
     * @param $config
     * @return mixed
     */
    private function do_connect($config){
        if(isset($config['type']) && $config['type'] == 'unix'){
            if (!isset($config['socket'])) {
                return 'redis config key [socket] not found';
            }
            $this->connect($config['socket']);
        }else{
            $port = isset($config['port']) ? intval($config['port']) : 6379;
            $timeout = isset($config['timeout']) ? intval($config['timeout']) : 300;
            $this->connect($config['host'], $port, $timeout);
        }

        if(isset($config['auth']) && !empty($config['auth'])){
            $this->auth($config['auth']);
        }

        $this->db = isset($config['database']) ? intval($config['database']) : 0;
        $this->select($this->db);
        $this->prefix = isset($config['prefix'])&& !empty($config['prefix']) ? $config['prefix'] : 'default:';
        $this->setOption(\Redis::OPT_PREFIX, $this->prefix );
        return $this;
    }

    /**
     * 切换数据库
     * @param $name
     * @return $this
     */
    public function switchDB($name){
        $arr = $this->config['database'];
        if(is_int($name)){
            $db = $name;
        }else{
            $db = isset($arr[$name]) ? $arr[$name] : 0;
        }
        if($db != $this->db){
            $this->select($db);
            $this->db = $db;
        }
        return $this;
    }

    /************************************  Some little tools  ************************************/

    /**
     * counter
     * @desc 创建计数器
     * @param $key
     * @param int $init
     * @param int $expire
     */
    public function counter($key,$init=0,$expire=0){
        if(empty($expire)){
            $this->set($key,$init);
        }else{
            $this->psetex($key,$expire,$init);
        }
    }

    /**
     * @desc 进行计数
     * @param $key
     * @return bool|int
     */
    public function count($key){
        if(!$this->exists($key)){
            return false;
        }
        $count = $this->incr($key);
        return $count;
    }

    function __destruct()
    {
        // TODO: Implement __destruct() method.
        $this->close();
    }
}
  • 修改redis配置,文件地址:/config/database.php
'redis' => [

        'cluster' => false,

        //
        'database'=>[
            'default_db'    => 0,
            'users_token'   => 1,
            'counter'       => 2,
        ],

        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
            'prefix' => 'default:'
        ],

    ],

使用示例

示例文件位置: /app/Http/Controllers/HomeController.php

<?php

namespace App\Http\Controllers;
use App\Service\Common\RedisService;
class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        // 实现功能,五秒内访问次数不能大于5次
        $redis = new RedisService();
        $key = 'test_counter_key';
        if(!$redis->exists($key)){
            $redis->counter('test_counter_key',0,'expire',5000);
        }

        $count = $redis->count($key);
        if($count>5){
            echo "操作次数过多(".$count.")";
        }else{
            echo $count;
        }
    }
}

其它资料

已有 2 条评论
  1. LEWISS LEWISS

    博主认为redis这个要不要做一个是连接池防止创建太多了连接?

    1. axios axios

      那把connect方法换成pconnect方法就好了,这个要视自己项目的需求情况修改代码的。
      这篇博文主要是为了记录自定义一个服务类都要做哪些工作。

添加新评论