PHP基于redis计数器类定义与用法示例


Posted in PHP onFebruary 08, 2018

本文实例讲述了PHP基于redis计数器类定义与用法。分享给大家供大家参考,具体如下:

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

这里使用其incr(自增)get(获取)delete(清除)方法来实现计数器类。

1.Redis计数器类代码及演示实例

RedisCounter.class.php

<?php
/**
 * PHP基于Redis计数器类
 * Date:  2017-10-28
 * Author: fdipzone
 * Version: 1.0
 *
 * Descripton:
 * php基于Redis实现自增计数,主要使用redis的incr方法,并发执行时保证计数自增唯一。
 *
 * Func:
 * public incr  执行自增计数并获取自增后的数值
 * public get   获取当前计数
 * public reset  重置计数
 * private connect 创建redis连接
 */
class RedisCounter{ // class start
  private $_config;
  private $_redis;
  /**
   * 初始化
   * @param Array $config redis连接设定
   */
  public function __construct($config){
    $this->_config = $config;
    $this->_redis = $this->connect();
  }
  /**
   * 执行自增计数并获取自增后的数值
   * @param String $key 保存计数的键值
   * @param Int  $incr 自增数量,默认为1
   * @return Int
   */
  public function incr($key, $incr=1){
    return intval($this->_redis->incr($key, $incr));
  }
  /**
   * 获取当前计数
   * @param String $key 保存计数的健值
   * @return Int
   */
  public function get($key){
    return intval($this->_redis->get($key));
  }
  /**
   * 重置计数
   * @param String $key 保存计数的健值
   * @return Int
   */
  public function reset($key){
    return $this->_redis->delete($key);
  }
  /**
   * 创建redis连接
   * @return Link
   */
  private function connect(){
    try{
      $redis = new Redis();
      $redis->connect($this->_config['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']);
      if(empty($this->_config['auth'])){
        $redis->auth($this->_config['auth']);
      }
      $redis->select($this->_config['index']);
    }catch(RedisException $e){
      throw new Exception($e->getMessage());
      return false;
    }
    return $redis;
  }
} // class end
?>

demo.php

<?php
Require 'RedisCounter.class.php';
// redis连接设定
$config = array(
  'host' => 'localhost',
  'port' => 6379,
  'index' => 0,
  'auth' => '',
  'timeout' => 1,
  'reserved' => NULL,
  'retry_interval' => 100,
);
// 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config);
// 定义保存计数的健值
$key = 'mycounter';
// 执行自增计数,获取当前计数,重置计数
echo $oRedisCounter->get($key).PHP_EOL; // 0
echo $oRedisCounter->incr($key).PHP_EOL; // 1
echo $oRedisCounter->incr($key, 10).PHP_EOL; // 11
echo $oRedisCounter->reset($key).PHP_EOL; // 1
echo $oRedisCounter->get($key).PHP_EOL; // 0
?>

输出:

0
1
11
1
0

2.并发调用计数器,检查计数唯一性

测试代码如下:

<?php
Require 'RedisCounter.class.php';
// redis连接设定
$config = array(
  'host' => 'localhost',
  'port' => 6379,
  'index' => 0,
  'auth' => '',
  'timeout' => 1,
  'reserved' => NULL,
  'retry_interval' => 100,
);
// 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config);
// 定义保存计数的健值
$key = 'mytestcounter';
// 执行自增计数并返回自增后的计数,记录入临时文件
file_put_contents('/tmp/mytest_result.log', $oRedisCounter->incr($key).PHP_EOL, FILE_APPEND);
?>

测试并发执行,我们使用ab工具进行测试,设置执行150次,15个并发。

ab -c 15 -n 150 http://localhost/test.php

执行结果:

ab -c 15 -n 150 http://localhost/test.php
This is ApacheBench, Version 2.3 <$Revision: 1554214 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking home.rabbit.km.com (be patient).....done
Server Software:    nginx/1.6.3
Server Hostname:    localhost
Server Port:      80
Document Path:     /test.php
Document Length:    0 bytes
Concurrency Level:   15
Time taken for tests:  0.173 seconds
Complete requests:   150
Failed requests:    0
Total transferred:   24150 bytes
HTML transferred:    0 bytes
Requests per second:  864.86 [#/sec] (mean)
Time per request:    17.344 [ms] (mean)
Time per request:    1.156 [ms] (mean, across all concurrent requests)
Transfer rate:     135.98 [Kbytes/sec] received
Connection Times (ms)
       min mean[+/-sd] median  max
Connect:    0  0  0.2   0    1
Processing:   3  16  3.2   16   23
Waiting:    3  16  3.2   16   23
Total:     4  16  3.1   17   23
Percentage of the requests served within a certain time (ms)
 50%   17
 66%   18
 75%   18
 80%   19
 90%   20
 95%   21
 98%   22
 99%   22
 100%   23 (longest request)

检查计数是否唯一

生成的总计数

wc -l /tmp/mytest_result.log
   150 /tmp/mytest_result.log

生成的唯一计数

sort -u /tmp/mytest_result.log | wc -l
   150

可以看到在并发调用的情况下,生成的计数也保证唯一。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP中Session的概念
Oct 09 PHP
一个PHP操作Access类(PHP+ODBC+Access)
Jan 02 PHP
php下载远程文件类(支持断点续传)
Nov 14 PHP
ExtJS与PHP、MySQL实现存储的方法
Apr 02 PHP
php simplexmlElement操作xml的命名空间实现代码
Jan 04 PHP
php中根据某年第几天计算出日期年月日的代码
Feb 24 PHP
PHP测试程序运行时间的类
Feb 05 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
Jun 03 PHP
HTML中嵌入PHP的简单方法
Feb 16 PHP
php截取视频指定帧为图片
May 16 PHP
Laravel中unique和exists验证规则的优化详解
Jan 28 PHP
PHP实现百度人脸识别
May 06 PHP
php处理抢购类功能的高并发请求
Feb 08 #PHP
php+redis实现商城秒杀功能
Nov 19 #PHP
php+redis消息队列实现抢购功能
Feb 08 #PHP
PHP多线程模拟实现秒杀抢单
Feb 07 #PHP
PHP设计模式之装饰器模式实例详解
Feb 07 #PHP
PHP使用星号替代用户名手机和邮箱的实现代码
Feb 07 #PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
Feb 07 #PHP
You might like
discuz Passport 通行证 整合笔记
2008/06/30 PHP
php发送短信验证码完成注册功能
2015/11/24 PHP
Codeigniter控制器controller继承问题实例分析
2016/01/19 PHP
Windows平台实现PHP连接SQL Server2008的方法
2017/07/26 PHP
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
js控制表单操作的常用代码小结
2013/08/15 Javascript
JS实现页面载入时随机显示图片效果
2016/09/07 Javascript
Vue组件tree实现树形菜单
2017/04/13 Javascript
原生JavaScript实现remove()和recover()功能示例
2018/07/24 Javascript
async/await优雅的错误处理方法总结
2019/01/30 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
vue--vuex详解
2019/04/15 Javascript
详解vue中使用微信jssdk
2019/04/19 Javascript
解决Vue+Electron下Vuex的Dispatch没有效果问题
2019/05/20 Javascript
vue多页面项目中路由使用history模式的方法
2019/09/23 Javascript
解决Echarts2竖直datazoom滑动后显示数据不全的问题
2020/07/20 Javascript
原生jQuery实现只显示年份下拉框
2020/12/24 jQuery
python实现电子词典
2020/04/23 Python
django自定义Field实现一个字段存储以逗号分隔的字符串
2014/04/27 Python
Python画图学习入门教程
2016/07/01 Python
python中单例常用的几种实现方法总结
2018/10/13 Python
利用python循环创建多个文件的方法
2018/10/25 Python
Python实现蒙特卡洛算法小实验过程详解
2019/07/12 Python
Python时间差中seconds和total_seconds的区别详解
2019/12/26 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
基于pytorch中的Sequential用法说明
2020/06/24 Python
Sublime Text3最新激活注册码分享适用2020最新版 亲测可用
2020/11/12 Python
python 实现弹球游戏的示例代码
2020/11/17 Python
python3代码中实现加法重载的实例
2020/12/03 Python
个人应聘自我评价分享
2013/11/18 职场文书
法人代表任命书范本
2014/06/05 职场文书
调研汇报材料范文
2014/08/17 职场文书
"9.18"国耻日演讲稿范文
2014/09/14 职场文书
计算机实训报告范文
2014/11/05 职场文书
Win11显卡控制面板打开显卡设置方法
2022/04/20 数码科技
mysql查看表结构的三种方法总结
2022/07/07 MySQL