1. 在宝塔环境下可直接进行安装2. 安装完成后需要进入指定的php环境下进行安装redis扩展3. 在thinkphp下进行自定义封装Redis类
<?php
namespace app\lib\cache;
use think\Config;
class Redis
{
private static $read_instance = null;
private static $write_instance = null;
public static function write()
{
$option = [
'host' => Config::get('cache.redis_w_host') ?? '127.0.0.1',
'port' => Config::get('cache.redis_w_port') ?? 6379,
];
if (is_null(self::$write_instance)) {
self::$write_instance = new \Redis();
self::$write_instance->connect($option['host'], $option['port']);
}
return self::$write_instance;
}
public static function read()
{
$option = [
'host' => Config::get('cache.redis_r_host') ?? '127.0.0.1',
'port' => Config::get('cache.redis_r_port') ?? 6379,
];
if (is_null(self::$read_instance)) {
self::$read_instance = new \Redis();
self::$read_instance->connect($option['host'], $option['port']);
}
return self::$read_instance;
}
//字符串类型------------------------------------------
/**
* 赋值 默认永久有效
* @param $key
* @param $value
* @param int $expire
* @return bool
*/
public static function set($key, $value, $expire = 0)
{
if ($expire == 0) {
return self::write()->set($key, $value);
} else {
return self::write()->setex($key, $expire, $value);
}
}
/**
* 查询缓存值,单个或数组
* @param $key 键
* @return mixed
*/
public static function get($key)
{
$func = is_array($key) ? 'getMulti' : 'get';
return self::read()->{$func}($key);
}
/**
* 自增
* @param $key
* @param int $number
* @return int
*/
public static function incr($key, $number = 1)
{
if ($number == 1) {
return self::write()->incr($key);
} else {
return self::write()->incrBy($key, $number);
}
}
/**
* 自减
* @param $key
* @param int $number
* @return int
*/
public static function decr($key, $number = 1)
{
if ($number == 1) {
return self::write()->decr($key);
} else {
return self::write()->decrBy($key, $number);
}
}
/**
* 获取字符串长度
* @param $key
* @return int
*/
public static function strlen($key)
{
return self::read()->strlen($key);
}
// Hash类型------------------------------------------
/**
* 赋单个值
* @param $key
* @param $field
* @param $value
* @return int
*/
public static function hSet($key, $field, $value)
{
return self::write()->hSet($key, $field, $value);
}
/**
* 取指定字段值,或取所有字段名和字段的值
* @param $key
* @param string $field
* @return array|string
*/
public static function hGet($key, $field = '')
{
if (empty($field)) {
return self::read()->hGetAll($key);
} else {
return self::read()->hGet($key, $field);
}
}
/**
* 赋多个值
* @param $key
* @param $data ['field1'=>'value1','field2'=>'value2']
* @return bool
*/
public static function hMset($key, $data)
{
return self::write()->hMset($key, $data);
}
/**
* 取多个值
* @param $key
* @param $dataField ['field1','field2']
* @return array
*/
public static function hMGet($key, $dataField)
{
return self::read()->hMGet($key, $dataField);
}
/**
* 获取字段的数量
* @param $key
* @return int
*/
public static function hLen($key)
{
return self::read()->hLen($key);
}
/**
* 自增
* @param $key
* @param $field
* @param int $number
* @return int
*/
public static function hIncrBy($key, $field, $number = 1)
{
return self::write()->hIncrBy($key, $field, $number);
}
// List类型------------------------------------------
/**
* 向列表左端添加元素
* @param $key
* @param $value
* @return int
*/
public static function lPush($key, $value)
{
return self::write()->lPush($key, $value);
}
/**
* 向列表右端弹出元素
* @param $key
* @return string
*/
public static function rPop($key)
{
return self::read()->rPop($key);
}
/**
* 返回列表的长度
* @param $key
* @return int
*/
public static function lLen($key)
{
return self::read()->lLen($key);
}
}
4.调用示例,简单商品秒杀
<?php
namespace app\api\controller\v1;
use app\lib\cache\Memcached;
use app\lib\cache\Redis;
class Test extends BaseController
{
public function t1($uid,$gid)
{
// return 'a';
// Memcached::set('t1','test2');
// echo Memcached::delete('t1');
// echo Memcached::get('t1');
// return Redis::hSet('test_1','name','刘先生');
//$r = Redis::hGet('test_1');
// 商品秒杀简单示例
// 准备1,商品秒杀状态 0正常秒杀中,1秒杀结束,这里需要与数据库秒杀商品字段同步
// 准备2,秒杀队列(用户ID),参与该次秒杀的人
// 准备3,秒杀n个,设置几个可以秒杀成功
// $uid = input('get.uid');
// $gid = input('get.gid');
$limit_number = 2;// 设置此商品只能2个人可以秒杀
$redis_ms_status = 'ms_status' . $gid;
$redis_ms_users = 'ms_users' . $gid;
// 判断当前的商品是否已结束
if (Redis::get($redis_ms_status) != 0) {
return [
'code' => '90002',
'msg' => '秒杀已经结束'
];
}
// 获取当前队列个数
$number = Redis::lLen($redis_ms_users);
if ($number >= $limit_number) { // 判断是否已秒杀完
Redis::set($redis_ms_status, 1);// 设置商品秒杀状态
return [
'code' => '90001',
'msg' => '秒杀失败'
];
}
// ... 判断其他情况,如该用户是否已成功参与了秒杀
// 秒杀成功
Redis::lPush($redis_ms_users, $uid);
return [
'code' => '90000',
'msg' => '秒杀成功'
];
}
// 后台查看秒杀结果流程
// 1.查看秒杀等同于把秒杀结果进行入库
// 注意1,查看前把商品秒杀状态设置为1,防止从右弹出一个单元时,左边又可以进行秒杀
// 注意2,弹出单元时,把秒杀信息进行入库,如果期中出现问题,需要把该单元重新压回,防止队列单元丢失
public function getMs($gid)
{
// $gid = input('get.gid');// 查看哪个秒杀商品
$redis_ms_status = 'ms_status' . $gid;
$redis_ms_users = 'ms_users' . $gid;
Redis::set($redis_ms_status, 1);//该商品秒杀状态设置1 秒杀已结束
for ($i = 0; $i <= Redis::lLen($redis_ms_users); $i++) {
$user_id = Redis::rPop($redis_ms_users);
//....... 其他业务逻辑处理,入库操作,异常处理,
echo '用户'.$user_id.'参与'.$gid.'号商品秒杀成功';
}
}
}