CI框架(CodeIgniter)操作redis的方法详解


Posted in PHP onJanuary 25, 2018

本文实例讲述了CI框架(CodeIgniter)操作redis的方法。分享给大家供大家参考,具体如下:

1. 在autoload.php 中加入 如下配置行

$autoload['libraries'] = array('redis');

2. 在/application/config 中加入文件 redis.php

文件内容如下:

<?php
// Default connection group
$config['redis_default']['host'] = 'localhost';   // IP address or host
$config['redis_default']['port'] = '6379';     // Default Redis port is 6379
$config['redis_default']['password'] = '';     // Can be left empty when the server does not require AUTH
$config['redis_slave']['host'] = '';
$config['redis_slave']['port'] = '6379';
$config['redis_slave']['password'] = '';
?>

3. 在 /application/libraries 中加入文件 Redis.php

文件来源:redis库文件包

文件内容:

<?php defined('BASEPATH') OR exit('No direct script access allowed');
/**
 * CodeIgniter Redis
 *
 * A CodeIgniter library to interact with Redis
 *
 * @package     CodeIgniter
 * @category    Libraries
 * @author     Joël Cox
 * @version     v0.4
 * @link      https://github.com/joelcox/codeigniter-redis
 * @link      http://joelcox.nl
 * @license     http://www.opensource.org/licenses/mit-license.html
 */
class CI_Redis {
  /**
   * CI
   *
   * CodeIgniter instance
   * @var   object
   */
  private $_ci;
  /**
   * Connection
   *
   * Socket handle to the Redis server
   * @var   handle
   */
  private $_connection;
  /**
   * Debug
   *
   * Whether we're in debug mode
   * @var   bool
   */
  public $debug = FALSE;
  /**
   * CRLF
   *
   * User to delimiter arguments in the Redis unified request protocol
   * @var   string
   */
  const CRLF = "\r\n";
  /**
   * Constructor
   */
  public function __construct($params = array())
  {
    log_message('debug', 'Redis Class Initialized');
    $this->_ci = get_instance();
    $this->_ci->load->config('redis');
    // Check for the different styles of configs
    if (isset($params['connection_group']))
    {
      // Specific connection group
      $config = $this->_ci->config->item('redis_' . $params['connection_group']);
    }
    elseif (is_array($this->_ci->config->item('redis_default')))
    {
      // Default connection group
      $config = $this->_ci->config->item('redis_default');
    }
    else
    {
      // Original config style
      $config = array(
        'host' => $this->_ci->config->item('redis_host'),
        'port' => $this->_ci->config->item('redis_port'),
        'password' => $this->_ci->config->item('redis_password'),
      );
    }
    // Connect to Redis
    $this->_connection = @fsockopen($config['host'], $config['port'], $errno, $errstr, 3);
    // Display an error message if connection failed
    if ( ! $this->_connection)
    {
      show_error('Could not connect to Redis at ' . $config['host'] . ':' . $config['port']);
    }
    // Authenticate when needed
    $this->_auth($config['password']);
  }
  /**
   * Call
   *
   * Catches all undefined methods
   * @param  string method that was called
   * @param  mixed  arguments that were passed
   * @return mixed
   */
  public function __call($method, $arguments)
  {
    $request = $this->_encode_request($method, $arguments);
    return $this->_write_request($request);
  }
  /**
   * Command
   *
   * Generic command function, just like redis-cli
   * @param  string full command as a string
   * @return mixed
   */
  public function command($string)
  {
    $slices = explode(' ', $string);
    $request = $this->_encode_request($slices[0], array_slice($slices, 1));
    return $this->_write_request($request);
  }
  /**
   * Auth
   *
   * Runs the AUTH command when password is set
   * @param  string password for the Redis server
   * @return void
   */
  private function _auth($password = NULL)
  {
    // Authenticate when password is set
    if ( ! empty($password))
    {
      // See if we authenticated successfully
      if ($this->command('AUTH ' . $password) !== 'OK')
      {
        show_error('Could not connect to Redis, invalid password');
      }
    }
  }
  /**
   * Clear Socket
   *
   * Empty the socket buffer of theconnection so data does not bleed over
   * to the next message.
   * @return NULL
   */
  public function _clear_socket()
  {
    // Read one character at a time
    fflush($this->_connection);
    return NULL;
  }
  /**
   * Write request
   *
   * Write the formatted request to the socket
   * @param  string request to be written
   * @return mixed
   */
  private function _write_request($request)
  {
    if ($this->debug === TRUE)
    {
      log_message('debug', 'Redis unified request: ' . $request);
    }
    // How long is the data we are sending?
    $value_length = strlen($request);
    // If there isn't any data, just return
    if ($value_length <= 0) return NULL;
    // Handle reply if data is less than or equal to 8192 bytes, just send it over
    if ($value_length <= 8192)
    {
      fwrite($this->_connection, $request);
    }
    else
    {
      while ($value_length > 0)
      {
        // If we have more than 8192, only take what we can handle
        if ($value_length > 8192) {
          $send_size = 8192;
        }
        // Send our chunk
        fwrite($this->_connection, $request, $send_size);
        // How much is left to send?
        $value_length = $value_length - $send_size;
        // Remove data sent from outgoing data
        $request = substr($request, $send_size, $value_length);
      }
    }
    // Read our request into a variable
    $return = $this->_read_request();
    // Clear the socket so no data remains in the buffer
    $this->_clear_socket();
    return $return;
  }
  /**
   * Read request
   *
   * Route each response to the appropriate interpreter
   * @return mixed
   */
  private function _read_request()
  {
    $type = fgetc($this->_connection);
    // Times we will attempt to trash bad data in search of a
    // valid type indicator
    $response_types = array('+', '-', ':', '$', '*');
    $type_error_limit = 50;
    $try = 0;
    while ( ! in_array($type, $response_types) && $try < $type_error_limit)
    {
      $type = fgetc($this->_connection);
      $try++;
    }
    if ($this->debug === TRUE)
    {
      log_message('debug', 'Redis response type: ' . $type);
    }
    switch ($type)
    {
      case '+':
        return $this->_single_line_reply();
        break;
      case '-':
        return $this->_error_reply();
        break;
      case ':':
        return $this->_integer_reply();
        break;
      case '$':
        return $this->_bulk_reply();
        break;
      case '*':
        return $this->_multi_bulk_reply();
        break;
      default:
        return FALSE;
    }
  }
  /**
   * Single line reply
   *
   * Reads the reply before the EOF
   * @return mixed
   */
  private function _single_line_reply()
  {
    $value = rtrim(fgets($this->_connection));
    $this->_clear_socket();
    return $value;
  }
  /**
   * Error reply
   *
   * Write error to log and return false
   * @return bool
   */
  private function _error_reply()
  {
    // Extract the error message
    $error = substr(rtrim(fgets($this->_connection)), 4);
    log_message('error', 'Redis server returned an error: ' . $error);
    $this->_clear_socket();
    return FALSE;
  }
  /**
   * Integer reply
   *
   * Returns an integer reply
   * @return int
   */
  private function _integer_reply()
  {
    return (int) rtrim(fgets($this->_connection));
  }
  /**
   * Bulk reply
   *
   * Reads to amount of bits to be read and returns value within
   * the pointer and the ending delimiter
   * @return string
   */
  private function _bulk_reply()
  {
    // How long is the data we are reading? Support waiting for data to
    // fully return from redis and enter into socket.
    $value_length = (int) fgets($this->_connection);
    if ($value_length <= 0) return NULL;
    $response = '';
    // Handle reply if data is less than or equal to 8192 bytes, just read it
    if ($value_length <= 8192)
    {
      $response = fread($this->_connection, $value_length);
    }
    else
    {
      $data_left = $value_length;
        // If the data left is greater than 0, keep reading
        while ($data_left > 0 ) {
        // If we have more than 8192, only take what we can handle
        if ($data_left > 8192)
        {
          $read_size = 8192;
        }
        else
        {
          $read_size = $data_left;
        }
        // Read our chunk
        $chunk = fread($this->_connection, $read_size);
        // Support reading very long responses that don't come through
        // in one fread
        $chunk_length = strlen($chunk);
        while ($chunk_length < $read_size)
        {
          $keep_reading = $read_size - $chunk_length;
          $chunk .= fread($this->_connection, $keep_reading);
          $chunk_length = strlen($chunk);
        }
        $response .= $chunk;
        // Re-calculate how much data is left to read
        $data_left = $data_left - $read_size;
      }
    }
    // Clear the socket in case anything remains in there
    $this->_clear_socket();
  return isset($response) ? $response : FALSE;
  }
  /**
   * Multi bulk reply
   *
   * Reads n bulk replies and return them as an array
   * @return array
   */
  private function _multi_bulk_reply()
  {
    // Get the amount of values in the response
    $response = array();
    $total_values = (int) fgets($this->_connection);
    // Loop all values and add them to the response array
    for ($i = 0; $i < $total_values; $i++)
    {
      // Remove the new line and carriage return before reading
      // another bulk reply
      fgets($this->_connection, 2);
      // If this is a second or later pass, we also need to get rid
      // of the $ indicating a new bulk reply and its length.
      if ($i > 0)
      {
        fgets($this->_connection);
        fgets($this->_connection, 2);
      }
      $response[] = $this->_bulk_reply();
    }
    // Clear the socket
    $this->_clear_socket();
    return isset($response) ? $response : FALSE;
  }
  /**
   * Encode request
   *
   * Encode plain-text request to Redis protocol format
   * @link  http://redis.io/topics/protocol
   * @param  string request in plain-text
   * @param  string additional data (string or array, depending on the request)
   * @return string encoded according to Redis protocol
   */
  private function _encode_request($method, $arguments = array())
  {
    $request = '$' . strlen($method) . self::CRLF . $method . self::CRLF;
    $_args = 1;
    // Append all the arguments in the request string
    foreach ($arguments as $argument)
    {
      if (is_array($argument))
      {
        foreach ($argument as $key => $value)
        {
          // Prepend the key if we're dealing with a hash
          if (!is_int($key))
          {
            $request .= '$' . strlen($key) . self::CRLF . $key . self::CRLF;
            $_args++;
          }
          $request .= '$' . strlen($value) . self::CRLF . $value . self::CRLF;
          $_args++;
        }
      }
      else
      {
        $request .= '$' . strlen($argument) . self::CRLF . $argument . self::CRLF;
        $_args++;
      }
    }
    $request = '*' . $_args . self::CRLF . $request;
    return $request;
  }
  /**
   * Info
   *
   * Overrides the default Redis response, so we can return a nice array
   * of the server info instead of a nasty string.
   * @return array
   */
  public function info($section = FALSE)
  {
    if ($section !== FALSE)
    {
      $response = $this->command('INFO '. $section);
    }
    else
    {
      $response = $this->command('INFO');
    }
    $data = array();
    $lines = explode(self::CRLF, $response);
    // Extract the key and value
    foreach ($lines as $line)
    {
      $parts = explode(':', $line);
      if (isset($parts[1])) $data[$parts[0]] = $parts[1];
    }
    return $data;
  }
  /**
   * Debug
   *
   * Set debug mode
   * @param  bool  set the debug mode on or off
   * @return void
   */
  public function debug($bool)
  {
    $this->debug = (bool) $bool;
  }
  /**
   * Destructor
   *
   * Kill the connection
   * @return void
   */
  function __destruct()
  {
    if ($this->_connection) fclose($this->_connection);
  }
}
?>

4. 然后你就可以 在文件中这样使用了

<?php
  if($this->redis->get('mark_'.$gid) === null){ //如果未设置
    $this->redis->set('mark_'.$gid, $giftnum); //设置
    $this->redis->EXPIRE('mark_'.$gid, 30*60); //设置过期时间 (30 min)
  }else{
    $giftnum = $this->redis->get('mark_'.$gid); //从缓存中直接读取对应的值
  }
?>

5. 重点是你所需要的 东东在这里很详细的讲解了

所有要用的函数只需要更改 $redis  ==> $this->redis

php中操作redis库函数功能与用法可参考本站https://3water.com/article/33887.htm

需要注意的是:

(1)你的本地需要安装 redis服务(windows安装)
(2)并开启redis 服务
(3)不管是windows 还是linux 都需要装 php对应版本的 redis扩展

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 替换模板变量实现步骤
Aug 24 PHP
PHP Memcached + APC + 文件缓存封装实现代码
Mar 11 PHP
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
Dec 29 PHP
PHP写杨辉三角实例代码
Jul 17 PHP
解析yii数据库的增删查改
Jun 20 PHP
常用PHP框架功能对照表
Oct 23 PHP
PHP静态文件生成类实例
Nov 29 PHP
php防止网站被攻击的应急代码
Oct 21 PHP
PHP简单获取及判断提交来源的方法
Apr 22 PHP
PHP 中常量的知识整理
Apr 14 PHP
php计数排序算法的实现代码(附四个实例代码)
Mar 31 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
Aug 26 PHP
PHP开发之用微信远程遥控服务器
Jan 25 #PHP
php实现统计二进制中1的个数算法示例
Jan 23 #PHP
基于php中echo用逗号和用点号的区别详解
Jan 23 #PHP
php数据结构之顺序链表与链式线性表示例
Jan 22 #PHP
通过源码解析Laravel的依赖注入
Jan 22 #PHP
phpstorm 正则匹配删除空行、注释行(替换注释行为空行)
Jan 21 #PHP
php语言注释,单行注释和多行注释
Jan 21 #PHP
You might like
无线电的诞生过程
2021/03/01 无线电
linux php mysql数据库备份实现代码
2009/03/10 PHP
smarty中js的调用方法示例
2014/10/27 PHP
浅谈PHP命令执行php文件需要注意的问题
2016/12/16 PHP
理解Javascript_01_理解内存分配原理分析
2010/10/11 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
2013/04/19 Javascript
JS预览图像将本地图片显示到浏览器上
2013/08/25 Javascript
jquery中获取id值方法小结
2013/09/22 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
开发插件的两个方法jquery.fn.extend与jquery.extend
2013/11/21 Javascript
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
2014/03/22 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
2015/08/12 Javascript
jQuery获取剪贴板内容的方法
2016/06/16 Javascript
js 自带的 map() 方法全面了解
2016/08/16 Javascript
String字符串截取的四种方式总结
2016/11/28 Javascript
BootStrapTable 单选及取值的实现方法
2017/01/10 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
Js判断H5上下滑动方向及滑动到顶部和底部判断的示例代码
2017/11/15 Javascript
vue权限路由实现的方法示例总结
2018/07/29 Javascript
python通过urllib2获取带有中文参数url内容的方法
2015/03/13 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
2016/05/24 Python
Python利用Beautiful Soup模块创建对象详解
2017/03/27 Python
Python模块搜索路径代码详解
2018/01/29 Python
Python通过调用mysql存储过程实现更新数据功能示例
2018/04/03 Python
pandas dataframe的合并实现(append, merge, concat)
2019/06/24 Python
pow在python中的含义及用法
2019/07/11 Python
python操作excel让工作自动化
2019/08/09 Python
使用Pycharm分段执行代码
2020/04/15 Python
HTML5之WebGL 3D概述(上)—WebGL原生开发开启网页3D渲染新时代
2013/01/31 HTML / CSS
HTML利用九宫格原理进行网页布局
2020/03/13 HTML / CSS
土耳其玩具商店:Toyzz Shop
2019/08/02 全球购物
人力资源行政经理自我评价
2013/10/23 职场文书
高考励志标语
2014/06/05 职场文书
就业意向书
2014/07/29 职场文书
党员专题组织生活会发言材料
2014/10/17 职场文书
Sql Server 行数据的某列值想作为字段列显示的方法
2022/04/20 SQL Server