前言
对于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;
}
}
}
其它资料
- phpredis 文档 GitHub
博主认为redis这个要不要做一个是连接池防止创建太多了连接?
那把connect方法换成pconnect方法就好了,这个要视自己项目的需求情况修改代码的。
这篇博文主要是为了记录自定义一个服务类都要做哪些工作。