PHPackages                             mr5/counter-rank - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. mr5/counter-rank

ActiveLibrary[Caching](/categories/caching)

mr5/counter-rank
================

counter and rank with redis

0.1.0(11y ago)51612MITPHPPHP &gt;=5.3

Since Aug 25Pushed 10y ago1 watchersCompare

[ Source](https://github.com/mr5/counter-rank)[ Packagist](https://packagist.org/packages/mr5/counter-rank)[ Docs](http://github.com/mr5/counter-rank)[ RSS](/packages/mr5-counter-rank/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (2)Used By (0)

[![Build Status](https://camo.githubusercontent.com/da1b3904ebb24f68d857b916aee7d0b9ecf64f8e9390302166fa373eaf5abb69/68747470733a2f2f7472617669732d63692e6f72672f6d72352f636f756e7465722d72616e6b2e737667)](https://travis-ci.org/mr5/counter-rank)[![License](https://camo.githubusercontent.com/e98afeb6a0fd926db53088c26da0931a703e309ba542971860ad6987cb823f66/68747470733a2f2f706f7365722e707567782e6f72672f6d72352f636f756e7465722d72616e6b2f6c6963656e73652e737667)](https://packagist.org/packages/mr5/counter-rank)

简介
--

[](#简介)

Counter-Rank 是一个使用 PHP 语言编写的、基于 Redis 的排名与计数类库，主要是对 Redis 的 zset 操作进行了封装。并提供了一个 [`JSClientHandler`](lib/mr5/CounterRank/JSClientHandler.php) 类，可以快速地生成 JsonP 接口用于满足一些静态页面的计数需求以及将数字渲染到页面。

本类库的源代码中有详细的注释，你可以使用类 PHPDoc 的工具生成 classes reference manual 。

安装
--

[](#安装)

在 `composer.json` 中添加：

```
{
	require: "mr5/counter-rank"
}
```

然后安装

```
composer install
```

注意事项
----

[](#注意事项)

打开 `phpunit.xml` 文件，找到以下片段：

```

```

如你要运行本类库的单元测试，请注意其中 `REDIS_NAMESPACE` 定义的命名空间，以防误删你的 Redis 数据。如有必要，可以修改该值。

基础使用
----

[](#基础使用)

```
use mr5\CounterRank\CounterRank;

// 命名空间 namespace 用于区分不同的项目。
// 分组名是一类 items 的分组。
// 比如要统计的是文章，则分组名可以是 articles，评论的分组名可以是 comments。
$counterRank = new CounterRank(
	'redis_host',
	'redis_port',
	'namespace',
	'分组名'
);

// 创建一个item，create 方法可以接收一个数字作为默认值，留空则为0。
// 下面的`900310`可以看做是文章 ID、评论 ID 等等。
$counterRank->create('900310', 0);

// 删除一个分组，`articles` 是分组名
$counterRank->deleteGroup('articles');

// 删除一个 item
$counterRank->delete('900310');

// 递增指定键名的值，如为负数则为递减。
// 这里对 `900310` 这篇文章递增了 1
$counterRank->increase('900310', 1);
// 递减
$counterRank->increase('900310', -1);

// 倒序排序，最多 10 个。
$counterRank->rank(10, 'desc');
// 正序排序，最多 10 个
$counterRank->rank(10, 'asc');
// 最高的 10 个
$counterRank->top10();
// 最低的 10 个
$counterRank->down10();

// 设置当操作一个不存在的 keys 时的处理闭包。
// 该闭包将接收两个参数，第一个参数是 key ，
// 第二个参数是当前 CounterRank 对象。
// 如修复后该 key 可以操作时返回 true，否则返回 false。
// 可以用于自动创建 item
$counterRank->setFixMiss(function($key, CounterRank $counterRank) {
            return $counterRank->create($key, 0) > 0;
});
```

JSClientHandler 的使用
-------------------

[](#jsclienthandler-的使用)

`JSClientHandler` 是一个用于生成 JS 客户端的工具类。 它可以实现以下功能：

- token 验证
- get: 读取指定分组指定键的数值;
- increase: 递增;
- rank: 获取排名;
- 指定 callback ，以实现 JsonP

以下是一个自定义控制器参考，请根据自己使用的框架以及需求进行修改，另外还建议阅读 [`JSClientHandler.php`](lib/mr5/CounterRank/JSClientHandler.php) 的源代码，内含详细的 PHP Doc：

```
use mr5\CounterRank\JSClientHandler;

/**
 *
 * JS 客户端控制器示例，请根据自己使用的框架以及需求进行修改
 *
 */
class ExampleController  extends Controller
{
	// 配置客户端的 token，键是分组名，值是 token 值。每个分组都必须指定，未指定的则不允许通过 JS Client 访问
    protected $tokens = array(
        'articles' => '1234567890JQK',
        'comments' => 'abcdefghijk'
    );
    protected $redis_host = 'localhost';
    protected $redis_port = 6379;

	// 命名空间，建议使用项目名称
    protected $namespace = 'project_name';
	// 递增的步长，如设置成负数，则 increase 方法执行的是递减
    protected $increaseStepSize = 1;

    // @var JSClientHandler|null
    protected $handlerInstance = null;

    public function __construct()
    {
        $this->handlerInstance = new JSClientHandler(
						$this->redis_host,
						$this->redis_port,
						$this->namespace,
						$this->tokens,
						$this->increaseStepSize
		);
    }

    // 读取
    public function getAction()
    {
        $this->handlerInstance->handleGet(
			$_REQUEST['token'],
			$_REQUEST['group'],
			$_REQUEST['keys'],
			$_REQUEST['callback']
		);
    }

    // 递增
    public function increaseAction()
    {
        $this->handlerInstance->handleIncrease(
			$_REQUEST['token'],
			$_REQUEST['group'],
			$_REQUEST['keys'],
			$_REQUEST['callback']
		);
    }

    // 排名
    public function rankAction()
    {
        $this->handlerInstance->handleRank(
			$_REQUEST['token'],
			$_REQUEST['group'],
			$_REQUEST['type'],
			$_REQUEST['limit'],
			$_REQUEST['callback']
		);
    }

    // 最高的十个数据
    public function top10Action()
    {
        $this->handlerInstance->handleTop10(
			$_REQUEST['token'],
			$_REQUEST['group'],
			$_REQUEST['callback']
		);

    }

    // 最低的十个数据
    public function down10Action()
    {
        $this->handlerInstance->handleDown10(
			$_REQUEST['token'],
			$_REQUEST['group'],
			$_REQUEST['callback']
		);

    }
}
```

### 自定义 token 验证规则

[](#自定义-token-验证规则)

token 默认验证方式是判断用户递交的 token 是否等于约定的 token ， 你可以通过传递一个闭包给 `setTokenVerifier` 方法来自定义这个验证规则。 下面是自定义 tokenVerifier 的例子：

```
$jsClientHandler->setTokenVerifier(function (
			$operation,	// 操作名
			$userToken, 	// 客户端提交的 token
			$token, 		// 服务器端约定的 token
			$group, 		// 分组名
			$keys) {
                $str = $token.$group;
                if($keys) {
                    $str .= $keys;
                }
                return md5($str) == $userToken;
            });
```

持久化计数数据
-------

[](#持久化计数数据)

[`CounterRank`](lib/mr5/CounterRank/CounterRank) 类提供了一个迭代器，通过 getIterator() 方法来获取迭代器，并迭代出计数器中所有的数据

下面是一个同步到数据库的例子：

```
// 注意：本操作可能耗时很长，请在命令行下执行并根据实际情况加入操作系统计划任务，而不是通过 web 请求执行

$counterRank = new CounterRank(
	'redis_host',
	'redis_port',
	'namespace',
	'分组名'
);
$conn = mysql_connect('localhost', 'username', 'password');
mysql_select_db('dbname', $conn);
mysql_set_charset('utf8', $conn);

foreach($counterRank->getIterator() as $items) {
    $values = '';
    foreach($items AS $post_id=>$heat) {
        if($values != '') {
            $values .= ',';
        }
        $values .= "({$post_id}, {$heat})";
    }
    mysql_query(
        "INSERT INTO `posts`(post_id, heat) VALUES  {$values} ON DUPLICATE KEY UPDATE heat=values(heat);",
        $conn
    );
});
```

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

4284d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e4d5b0b545af8e9117d9432169f694675d8e601ce7ffe62317fff2e63e8092cf?d=identicon)[mr5](/maintainers/mr5)

---

Top Contributors

[![mr5](https://avatars.githubusercontent.com/u/3281595?v=4)](https://github.com/mr5 "mr5 (38 commits)")

---

Tags

rediscounterrank

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mr5-counter-rank/health.svg)

```
[![Health](https://phpackages.com/badges/mr5-counter-rank/health.svg)](https://phpackages.com/packages/mr5-counter-rank)
```

###  Alternatives

[predis/predis

A flexible and feature-complete Redis/Valkey client for PHP.

7.8k305.7M2.4k](/packages/predis-predis)[snc/redis-bundle

A Redis bundle for Symfony

1.0k39.4M67](/packages/snc-redis-bundle)[awssat/laravel-visits

Laravel Redis visits counter for Eloquent models

975163.6k2](/packages/awssat-laravel-visits)[clue/redis-protocol

A streaming Redis protocol (RESP) parser and serializer written in pure PHP.

5311.0M13](/packages/clue-redis-protocol)[rtcamp/nginx-helper

Cleans nginx's fastcgi/proxy cache or redis-cache whenever a post is edited/published. Also provides cloudflare edge cache purging with Cache-Tags.

23817.0k1](/packages/rtcamp-nginx-helper)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
