欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-09-02 13:31:08
本文实例讲述了ci框架(codeigniter)操作redis的方法。分享给大家供大家参考,具体如下: 1. 在autoload.php 中加入 如下配置行 $...

本文实例讲述了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

文件来源:

文件内容:

<?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库函数功能与用法可参考本站

需要注意的是:

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

更多关于codeigniter相关内容感兴趣的读者可查看本站专题:《codeigniter入门教程》、《ci(codeigniter)框架进阶教程》、《php优秀开发框架总结》、《thinkphp入门教程》、《thinkphp常用方法总结》、《zend framework框架入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

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