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下实现一个阿拉伯数字转中文数字的函数
Jul 10 PHP
让PHP COOKIE立即生效,不用刷新就可以使用
Mar 09 PHP
PHP代码网站如何防范SQL注入漏洞攻击建议分享
Mar 01 PHP
php中判断文件空目录是否有读写权限的函数代码
Aug 07 PHP
zend Framework中的Layout(模块化得布局)详解
Jun 28 PHP
php正则匹配html中带class的div并选取其中内容的方法
Jan 13 PHP
php+mysqli事务控制实现银行转账实例
Jan 29 PHP
PHP使用DOM和simplexml读取xml文档的方法示例
Feb 08 PHP
在PHP 7下安装Swoole与Yar,Yaf的方法教程
Jun 02 PHP
PHP并发查询MySQL的实例代码
Aug 09 PHP
PHP实现简单的模板引擎功能示例
Sep 02 PHP
一文搞懂PHP中的抽象类和接口
May 25 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
PHP extract 将数组拆分成多个变量的函数
2010/06/30 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
PHP防止跨域提交表单
2013/11/01 PHP
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
2015/01/13 Javascript
jquery制作属于自己的select自定义样式
2015/11/23 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
Node.js制作简单聊天室
2017/01/12 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
ES6学习教程之对象的扩展详解
2017/05/02 Javascript
js 开发之autocomplete=&quot;off&quot;在chrom中失效的解决办法
2017/09/28 Javascript
js前端导出Excel的方法
2017/11/01 Javascript
Vue.js用法详解
2017/11/13 Javascript
微信小程序实现图片上传、删除和预览功能的方法
2017/12/18 Javascript
如何去除vue项目中的#及其ie9兼容性
2018/01/11 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
webpack-dev-server远程访问配置方法
2018/02/22 Javascript
微信小程序左滑动显示菜单功能的实现
2018/06/14 Javascript
JS实现的贪吃蛇游戏完整实例
2019/01/18 Javascript
Python装饰器的函数式编程详解
2015/02/27 Python
Python Matplotlib库安装与基本作图示例
2019/01/09 Python
Python常用特殊方法实例总结
2019/03/22 Python
关于python3.7安装matplotlib始终无法成功的问题的解决
2020/07/28 Python
如何使用scrapy中的ItemLoader提取数据
2020/09/30 Python
Pandas直接读取sql脚本的方法
2021/01/21 Python
印度低票价航空公司:GoAir
2017/10/11 全球购物
Herve Leger官网:标志性绷带连衣裙等
2018/12/26 全球购物
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
电子商务专业个人的自我评价
2013/12/19 职场文书
计算机毕业大学生求职信
2014/06/26 职场文书
2015年教师节新闻稿
2015/07/17 职场文书
nginx里的rewrite跳转的实现
2021/03/31 Servers
浅谈golang 中time.After释放的问题
2021/05/05 Golang
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL
宫崎骏十大动画电影,宫崎骏好看的动画电影排名
2022/03/22 日漫
Java 超详细讲解数据结构中的堆的应用
2022/04/02 Java/Android