排行榜功能幾乎存在于所有項目中,如按照發布時間倒序的新聞列表,按照考試成績正序的成績表,按照瀏覽量從大到小的話題。Redis 中列表和有序集合兩種數據結構都非常適合用于排行榜系統中。
本文采用使用有序集合來開發一個投票項目來演示排行榜。
## 1.創建投票選項
### 1.1 創建投票方法
使用`Request::instance()->post()`接受數據保存到數據庫
~~~
public function create()
{
if (Request::instance()->isPost()) {
$itemModel = new ItemModel();
if ($itemModel->isUpdate(false)->save(Request::instance()->post())) {
return '創建成功';
}
return '創建失敗';
}
return "創建選項";
}
~~~
### 1.2 模型事件
創建到數據庫的數據后續使用 ThinkPHP5 的模型事件將數據保存到 Redis
~~~
<?php
namespace app\index\model;
use think\Model;
class Item extends Model
{
protected $autoWriteTimestamp = 'datetime';
protected static function init()
{
self::event('before_insert', function ($event) {
// 創建前將票數設置為0
$event->count = 0;
});
// 數據創建成功后將數據保存到 Redis
self::event('after_insert', function ($event) {
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$redis->zAdd("item", $event->count, $event->id);
});
}
}
~~~
## 2\. 獲取投票列表
~~~
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$count = $redis->zCard("item");
$multi = $redis->zRange('zset', 0, $count - 1, true);
var_dump($multi);
~~~
## 3\. 投票
~~~
$item_id = Request::instance()->post('item_id');
$redis->zIncrBy('item', 1, $item_id); // 給$item_id加一票
~~~
## 4\. 統計排名
~~~
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$count = $redis->zCard("item");
// 返回分數從高到低排序的前10名及分數
$revRange = $redis-> zRevRange('item', 0, $count - 1, true);
var_dump($revRange);
~~~