在 PHP对Redis键空间通知过期事件的应用实例 一文中,已经介绍了PHP对Redis键空间通知功能的应用。本文主要介绍laravel中对Redis键空间通知过期事件的应用。
场景:用户下单后一个小时如果没付款就取消掉订单。
要实现这个,有了前文的基础,我们肯定不会只想到crontab定时去做,还会想到用Redis去实现。那么具体该怎么操作?请往下看:
1、先配置一下 .env 文件 ,缓存设置为Redis。
CACHE_DRIVER=redis
2、在控制器中新增订单的方法中加入缓存。
Cache::store('redis')->put('ORDER_CONFIRM:'.$order->id,$order->id,1); // 1分钟后过期。这里为了测试方便,暂设置为1分钟。 复制代码
3、自定义artisan命令。
php artisan make:command OrderExpireListen
app\Console\Commands\OrderExpireListen.php文件
<?php namespace App\Console\Commands; use App\Model\Order; use Illuminate\Console\Command; use Illuminate\Support\Facades\Redis; class OrderExpireListen extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'order:expire'; /** * The console command description. * * @var string */ protected $description = '监听订单创建,在1分钟后如果没付款取消订单。'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $cachedb = config('database.redis.cache.database', 0); $pattern = '__keyevent@' . $cachedb . '__:expired'; Redis::subscribe($pattern, function ($channel) { // 订阅键过期事件 // laravel_cache:ORDER_CONFIRM:7 这样的格式 $channel = trim(strstr($channel, ':'), ':'); $key_type = str_before($channel, ':'); switch ($key_type) { case 'ORDER_CONFIRM': $order_id = str_after($channel, ':'); // 取出订单 ID $order = Order::query()->find($order_id); if ($order) { // 执行取消操作 $order->status = 2; $order->save(); } break; case 'ORDER_OTHEREVENT': break; default: break; } }); } } 复制代码
laravel_cache:ORDER_CONFIRM:7 这个可以通过下面方法查询:
127.0.0.1:6379> keys * 1) "laravel_cache:ORDER_CONFIRM:7" 复制代码
过期后,我们在Redis客户端可以看到如下内容:
127.0.0.1:6379> psubscribe __keyevent@0__:expired Reading messages... (press Ctrl-C to quit) 1) "psubscribe" 2) "__keyevent@0__:expired" 3) (integer) 1 1) "pmessage" 2) "__keyevent@0__:expired" 3) "__keyevent@0__:expired" 4) "laravel_cache:5c785c036466adea360111aa28563bfd556b5fba" 1) "pmessage" 2) "__keyevent@0__:expired" 3) "__keyevent@0__:expired" 4) "laravel_cache:5c785c036466adea360111aa28563bfd556b5fba:timer" 1) "pmessage" 2) "__keyevent@0__:expired" 3) "__keyevent@0__:expired" 4) "laravel_cache:ORDER_CONFIRM:7"