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 相关文章推荐
如何限制访问者的ip(PHPBB的代码)
Oct 09 PHP
php面向对象全攻略 (十一)__toString()用法 克隆对象 __call处理调用错误
Sep 30 PHP
php microtime获取浮点的时间戳
Feb 21 PHP
PHP运行出现Notice : Use of undefined constant 的完美解决方案分享
Mar 05 PHP
PHP获取和操作配置文件php.ini的几个函数介绍
Jun 24 PHP
解析php5配置使用pdo
Jul 03 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
Jul 08 PHP
百度实时推送api接口应用示例
Oct 21 PHP
php判断一个数组是否为有序的方法
Mar 27 PHP
php获取网页上所有链接的方法
Apr 03 PHP
Laravel框架数据库迁移操作实例详解
Apr 06 PHP
PHP7 整型处理机制修改
Mar 09 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
从零开始学YII2框架(二)通过 Composer 安装扩展插件
2014/08/20 PHP
php进行支付宝开发中return_url和notify_url的区别分析
2014/12/22 PHP
PHP上传文件时自动分配路径的方法
2015/01/09 PHP
PHP判断浏览器、判断语言代码分享
2015/03/05 PHP
浅谈php中urlencode与rawurlencode的区别
2016/09/05 PHP
Laravel 在views中加载公共页面的实现代码
2019/10/22 PHP
PHP接口类(interface)的定义、特点和应用示例
2020/05/18 PHP
javascript vvorld 在线加密破解方法
2008/11/13 Javascript
jQuery filter函数使用方法
2014/05/19 Javascript
Express的路由详解
2015/12/10 Javascript
详解nodejs模板引擎制作
2017/06/14 NodeJs
AngularJs实现聊天列表实时刷新功能
2017/06/15 Javascript
理解 Node.js 事件驱动机制的原理
2017/08/16 Javascript
JS中用EL表达式获取上下文参数值的方法
2018/03/28 Javascript
详解react内联样式使用webpack将px转rem
2018/09/13 Javascript
微信小程序使用setData修改数组中单个对象的方法分析
2018/12/30 Javascript
JavaScript实现抖音罗盘时钟
2019/10/11 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
[00:57]辉夜杯战队访谈宣传片—VG
2015/12/25 DOTA
[48:20]OpTic vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python模糊查询本地文件夹去除文件后缀的实例(7行代码)
2017/11/09 Python
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
python求质数的3种方法
2018/09/28 Python
python pands实现execl转csv 并修改csv指定列的方法
2018/12/12 Python
详解python中的hashlib模块的使用
2019/04/22 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
Python 实现网课实时监控自动签到、打卡功能
2020/03/12 Python
python实现发送邮件
2021/03/02 Python
IE10 Error.stack 让脚本调试更加方便快捷
2013/04/22 HTML / CSS
三星英国官网:Samsung英国
2018/09/25 全球购物
Linux Interview Questions For software testers
2013/05/17 面试题
《美丽的小兴安岭》教学反思
2014/02/26 职场文书
2014年教师节红领巾广播稿
2014/09/10 职场文书
婚宴父母致辞
2015/07/27 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
漫画「请问您今天要来点兔子吗?」最新杂志彩页公开
2022/03/24 日漫