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

本文实例讲述了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+redis数据库程序设计技巧总结》、《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

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

您可能感兴趣的文章:

  • php操作redis中的hash和zset类型数据的方法和代码例子
  • PHP实现操作redis的封装类完整实例
  • php 使用redis锁限制并发访问类示例
  • php实现的redis缓存类定义与使用方法示例
  • PHP实现的Redis多库选择功能单例类
  • php Redis函数用法实例总结【附php连接redis单例类】
  • 30个php操作redis常用方法代码例子
  • php Session存储到Redis的方法
  • php操作redis缓存方法分享
  • php结合redis实现高并发下的抢购、秒杀功能的实例
(0)

相关推荐

  • 30个php操作redis常用方法代码例子

    redis的操作很多的,以前看到一个比较全的博客,但是现在找不到了.查个东西搜半天,下面整理一下php处理redis的例子,个人觉得常用一些例子.下面的例子都是基于php-redis这个扩展的. 1,connect 描述:实例连接到一个Redis. 参数:host: string,port: int 返回值:BOOL 成功返回:TRUE;失败返回:FALSE 示例: 复制代码 代码如下: <?php  $redis = new redis();  $result = $redis->conne

  • PHP实现操作redis的封装类完整实例

    本文实例讲述了PHP实现操作redis的封装类.分享给大家供大家参考,具体如下: <?php /** * Redis 操作,支持 Master/Slave 的负载集群 * * @author jackluo */ class RedisCluster{ // 是否使用 M/S 的读写集群方案 private $_isUseCluster = false; // Slave 句柄标记 private $_sn = 0; // 服务器连接句柄 private $_linkHandle = array

  • php实现的redis缓存类定义与使用方法示例

    本文实例讲述了php实现的redis缓存类定义与使用方法.分享给大家供大家参考,具体如下: php+redis缓存类 <?php class redisCache { /** * $host : redis服务器ip * $port : redis服务器端口 * $lifetime : 缓存文件有效期,单位为秒 * $cacheid : 缓存文件路径,包含文件名 */ private $host; private $port; private $lifetime; private $cachei

  • php Redis函数用法实例总结【附php连接redis单例类】

    本文实例总结了php Redis函数用法.分享给大家供大家参考,具体如下: 一直在拿PHP使用Redis,但是总感觉不牢靠,索性借这个时间空余一气呵成, 把PHP中所有操作到的Redis命令,几乎全敲个遍,包括它的返回值都是盯对过的,哪怕下回忘了也可以直接过来查嘛~大家也可以放心使用. 测试环境:    PHP:5.5     Redis:2.4.6 参考网址:   https://github.com/phpredis/phpredis Tips: 对于:string, set , sort

  • PHP实现的Redis多库选择功能单例类

    本文实例讲述了PHP实现的Redis多库选择功能单例类.分享给大家供大家参考,具体如下: 前言 qq群里有同学问redis如何进行多库选择,用php实现了一下,还望各位多多指点 代码 <?php class MultiRedisConnect { /** * hostname * * @var string */ const REDISHOSTNAME = "127.0.0.1"; /** * port * * @var int */ const REDISPORT = 6379

  • php Session存储到Redis的方法

    当然要写先安装php的扩展,可参考这篇文章:Redis及PHP扩展安装修改php.ini的设置 复制代码 代码如下: session.save_handler = redissession.save_path = "tcp://127.0.0.1:6379″修改后重启php-fpm或nginx,phpinfo() session redis如果不想修改php.ini可这样 复制代码 代码如下: ini_set("session.save_handler","redi

  • php操作redis缓存方法分享

    php redis缓存操作 <?php /** * Redis缓存操作 * @author hxm * @version 1.0 * @since 2015.05.04 */ class RCache extends Object implements CacheFace { private $redis = null; //redis对象 private $sId = 1; //servier服务ID private $con = null;//链接资源 /** * 初始化Redis * *

  • php 使用redis锁限制并发访问类示例

    本文介绍了php 使用redis锁限制并发访问类,并详细的介绍了并发访问限制方法. 1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制的情况下,用户则可以使用同一个换领码同时兑换到多张优惠券. 伪代码如下: if A(可以换领)     B(执行换领)     C(更新为已换领) D(结束) 如果用户并发提交换领码,都能通过可以换领(A)的判断,因

  • php结合redis实现高并发下的抢购、秒杀功能的实例

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到用缓存来处理抢购,避免直接操作数据库,例如使用Redis. 重点在于第二个问题 常规写法: 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数 <?php $conn=mysql_connect("localho

  • php操作redis中的hash和zset类型数据的方法和代码例子

    前面一篇博客主要是string类型,list类型和set类型,下面hash类型和zset类型 1,hset 描述:将哈希表key中的域field的值设为value.如果key不存在,一个新的哈希表被创建并进行HSET操作.如果域field已经存在于哈希表中,旧值将被覆盖. 参数:key field value 返回值:如果field是哈希表中的一个新建域,并且值设置成功,返回1.如果哈希表中域field已经存在且旧值已被新值覆盖,返回0. 2,hsetnx 描述:将哈希表key中的域field的

随机推荐