当前位置: 移动技术网 > IT编程>开发语言>PHP > CI框架(CodeIgniter)操作redis的方法详解

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

2018年01月29日  | 移动技术网IT编程  | 我要评论

马关县林业局,极品废妾,河海大学天空教室

本文实例讲述了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程序设计有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网