redis 排行榜

屁话不多说,直接上代码

<?php

/**使用redis的排行榜
 * Class RedisLeaderboard
 */
class RedisLeaderboard
{


    private $redis;
    private $collection;

    /**
     * 构造函数
     * @param object $redis 已连接redis的phpredis的对象
     * @param string $collectionKey 字符串,排行榜的key名
     */
    public function __construct($redis = [], $collectionKey = '')
    {

        if ($redis) {
            $this->redis = $redis;
        } else {
            $this->redis = new \Redis();
            $this->redis->connect('127.0.0.1');
        }

        if ($collectionKey) {
            //这里不会检查当前的key值是否存在,是为了方便重新访问对应的排行榜
            $this->collection = $collectionKey;
        } else {
            $this->collection = 'collection:' . $this->msectime();
            while (!empty($this->redis->exists($this->collection))) {
                $this->collection = 'collection:' . $this->msectime();
            }
        }

    }

    //返回当前的毫秒时间戳
    public function msectime()
    {
        list($msec, $sec) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

    /**
     * 获取当前的排行榜的key名
     * @return string
     */
    public function getCollection()
    {
        return $this->collection;
    }

    /**
     * @param $key //节点名称
     * @param int $value //节点值
     * @return int
     */
    public function addCollection($key, $value = 1)
    {
        return $this->redis->zAdd($this->collection, $value, $key);
    }

    /**
     * 给出对应的排行榜
     * @param int $number 需要给出排行榜数目
     * @param bool $asc 排序顺序 true为按照高分为第0
     * @param bool $withscores 是否需要分数
     * @param callback $callback 用于处理排行榜的回调函数
     * @return [] 对应排行榜
     */
    public function getCollectionList($start, $end, $asc = true, $withscores = false, $callback = null)
    {
        if ($asc) {
            $nowLeadboard = $this->redis->zRevRange($this->collection, $start, $end - 1, $withscores);//按照高分数顺序排行;
        } else {
            $nowLeadboard = $this->redis->zRange($this->collection, $start, $end - 1, $withscores);//按照低分数顺序排行;
        }


        if ($callback) {
            //使用回调处理
            return $callback($nowLeadboard);
        } else {
            return $nowLeadboard;
        }
    }

    /**获取给定节点的排名
     * @param string $node 对应的节点的key名
     * @param string $asc 是否按照分数大小正序排名, true的情况下分数越大,排名越高
     * @return int
     */
    public function getNodeRank($node, $asc = true)
    {
        if ($asc) {
            //zRevRank 分数最高的排行为0,所以需要加1位
            return $this->redis->zRevRank($this->collection, $node);
        } else {
            return $this->redis->zRank($this->collection, $node);
        }
    }

    /**获取分页显示的数据
     * @param $page
     * @param $pageSize
     * @param bool $asc
     * @param bool $withscores
     * @param null $callback
     * @return array
     */
    public function getPageCollection($page, $pageSize = 100, $asc = true, $withscores = true, $callback = null)
    {
        return $this->getCollectionList(($page - 1) * $pageSize, $pageSize * $page, $asc, $withscores, $callback);
    }

    public function getCount()
    {
        return $this->redis->zCard($this->collection);
    }

}

$time = time();

//一下的为使用样例
$class = new RedisLeaderboard([], date('Y-m-d-H'));

for ($i = 1; $i <= 500; $i++) {
    $class->addCollection($i, $i);
}

$count = $class->getCount();
$pageSize = 200;

for ($i = 1; $i <= ceil($count / $pageSize); $i++) {
    $res = $class->getPageCollection($i, $pageSize);
    echo "<pre>";
    print_r($res);
}

echo "总数量为:{$count}花费时间是:" . (time() - $time);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值