修正thinkphp 3.2 的一個BUG: ERR: Redis server went away

之1、 Thinkphp3.2數據庫連查方法cache()時個bug會致使查詢失敗php

ERR: Redis server went away

獲取不到Conf/redis.php的配置,全局方法S()是沒有問題的,替換ThinkPHP/Library/Think/Cache/Driver/Redis.class.php的__construct()方法來修正。代碼以下:html

public function __construct($options=array()) {
    if ( !extension_loaded('redis') ) {
        E(L('_NOT_SUPPERT_').':redis');
    }
    if(empty($options)) {
        $options = array (
            'host'          => C('REDIS_HOST') ? C('REDIS_HOST') : '127.0.0.1',
            'port'          => C('REDIS_PORT') ? C('REDIS_PORT') : 6379,
            'timeout'       => C('DATA_CACHE_TIMEOUT') ? C('DATA_CACHE_TIMEOUT') : false,
            'auth'    => C('REDIS_AUTH') ? C('REDIS_AUTH'):null,//auth認證
            'persistent'    => false,
        );
    }
    $this->options =  $options;
    $this->options['expire'] =  isset($options['expire'])?  $options['expire']  :   C('DATA_CACHE_TIME');
    $this->options['prefix'] =  isset($options['prefix'])?  $options['prefix']  :   C('DATA_CACHE_PREFIX');
    $this->options['length'] =  isset($options['length'])?  $options['length']  :   0;
    $this->options['persistent'] =  isset($options['persistent'])?  $options['persistent']  :   C('REDIS_PERSISTENT');
    $func = $options['persistent'] ? 'pconnect' : 'connect';
    $this->handler  = new \Redis;

    //2018.9.4 修正cache()方法連查時沒有獲取到配置的bug
    if(!isset($this->options['host'])){
        $this->options['host'] = $options['host'] = C('REDIS_HOST') ? C('REDIS_HOST') : '127.0.0.1';
    }
    if(!isset($this->options['port'])){
        $this->options['port'] = $options['port'] = C('REDIS_PORT') ? C('REDIS_PORT') : 6379;
    }
    if(!isset($this->options['timeout'])){
        $this->options['timeout'] = $options['timeout'] = C('REDIS_TIMEOUT') ? C('REDIS_TIMEOUT') : 300;
    }
    if(!isset($this->options['auth'])){
        $this->options['auth'] = $options['auth'] = C('REDIS_AUTH') ? C('REDIS_AUTH') : null;
    }
    if(!isset($this->options['expire'])){
        $this->options['expire'] = $options['expire'] = C('DATA_CACHE_TIME') ? C('DATA_CACHE_TIME') : 0;
    }

    $options['timeout'] === false ?
        $this->handler->$func($options['host'], $options['port']) :
        $this->handler->$func($options['host'], $options['port'], $options['timeout']);


    //Auth參數
    if($this->options['auth']!=null)
    {
        $this->handler->auth($this->options['auth']);
    }
}

之2、另外,此版本的Cache.class.php獲取靜態實例對象也有一個BUG,修正代碼以下:git

 

static function getInstance($type='',$options=array()) {
static $_instance  =  array();

      //--BEGIN: http://www.thinkphp.cn/bug/3491.html
      $options_array = array();
      if(isset($options['type']) && !empty($options['type'])){
          $options_array['type'] = $options['type'];
      }else{
          $options_array['type'] = $type;
      }
      if(isset($options['host']) && !empty($options['host'])){
          $options_array['host'] = $options['host'];
      }
      if(isset($options['port']) && !empty($options['port'])){
          $options_array['port'] = $options['port'];
      }
      //--END

$guid  =  $type.to_guid_string($options_array);
if(!isset($_instance[$guid])){
   $obj   =  new Cache();
   $_instance[$guid]  =  $obj->connect($type,$options);
}
return $_instance[$guid];
  }

由於使用$options參數進行初始化時,$options裏會帶有緩存key,而這個key是常常變化的,不能做爲惟一實例的判斷條件,及後面的to_guid_string方法去使用。 github

 

之3、redis.conf配置參數DATA_CACHE_TIME注意不要設置成0,有的說設成0是永久緩存,查看了redis的官方函數,好像沒有說明這一點,因此最好設置一個大於0的數字,以免緩存沒有生效。(這裏還有幾個issue1 issue2 說明了不要設成0)redis

相關文章
相關標籤/搜索