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递归创建和删除文件夹的代码小结
Apr 13 PHP
国外十大最流行的PHP框架排名
Jul 04 PHP
php读取图片内容并输出到浏览器的实现代码
Aug 08 PHP
php json_encode值中大括号与花括号区别
Sep 30 PHP
PHP关于htmlspecialchars、strip_tags、addslashes的解释
Jul 04 PHP
thinkphp的URL路由规则与配置实例
Nov 26 PHP
php获取用户浏览器版本的方法
Jan 03 PHP
Yii实现显示静态页的方法
Apr 25 PHP
功能强大的php文件上传类
Aug 29 PHP
PHP二进制与字符串之间的相互转换教程
Oct 14 PHP
使用php自动备份数据库表的实现方法
Jul 28 PHP
php设计模式之抽象工厂模式分析【星际争霸游戏案例】
Jan 23 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
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
2013/07/18 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(一)
2014/06/23 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
2016/01/07 PHP
PHP图片裁剪与缩放示例(无损裁剪图片)
2017/02/08 PHP
Yii2选项卡的简单使用
2017/05/26 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
学习ExtJS accordion布局
2009/10/08 Javascript
javascript中利用数组实现的循环队列代码
2010/01/24 Javascript
javascript中创建对象的三种常用方法
2010/12/30 Javascript
获得所有表单值的JQuery实现代码[IE暂不支持]
2012/05/24 Javascript
动态加载脚本提升javascript性能
2014/02/24 Javascript
jQuery插件zoom实现图片全屏放大弹出层特效
2015/04/15 Javascript
JavaScript实现鼠标点击后层展开效果的方法
2015/05/13 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
微信扫码支付零云插件版实例详解
2017/04/26 Javascript
layui下拉列表select实现可输入查找的方法
2019/09/28 Javascript
用python实现面向对像的ASP程序实例
2014/11/10 Python
Python的批量远程管理和部署工具Fabric用法实例
2015/01/23 Python
详解Python实现多进程异步事件驱动引擎
2017/08/25 Python
10个Python小技巧你值得拥有
2018/09/29 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
selenium+python截图不成功的解决方法
2019/01/30 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
Python爬取数据保存为Json格式的代码示例
2019/04/09 Python
python数据挖掘需要学的内容
2019/06/23 Python
Flask教程之重定向与错误处理实例分析
2019/08/01 Python
python matplotlib折线图样式实现过程
2019/11/04 Python
原来我一直安装 Python 库的姿势都不对呀
2019/11/11 Python
flask框架渲染Jinja模板与传入模板变量操作详解
2020/01/25 Python
使用python批量修改XML文件中图像的depth值
2020/07/22 Python
Python爬虫教程知识点总结
2020/10/19 Python
Python实例教程之检索输出月份日历表
2020/12/16 Python
保证书格式
2015/01/16 职场文书
2016年助残日旅游活动总结
2016/04/01 职场文书
java实现面板之间切换功能
2022/06/10 Java/Android