1. 程式人生 > >thinkphp 3.2裡面session的redis驅動檔案(可分散式)

thinkphp 3.2裡面session的redis驅動檔案(可分散式)

使用方法:
將檔案存放在ThinkPHP框架根目錄下的Library\Think\Session\Driver\目錄下


config配置引數:
//Redis Session配置
'SESSION_AUTO_START'=>  true,// 是否自動開啟Session
'SESSION_TYPE'=>  'Redis',//session型別
'SESSION_PERSISTENT'    =>  1,//是否長連線(對於php來說0和1都一樣)
'SESSION_CACHE_TIME'=>  1,//連線超時時間(秒)
'SESSION_EXPIRE'=>  0,//session有效期(單位:秒) 0表示永久快取
'SESSION_PREFIX'=>  'sess_',//session字首
'SESSION_REDIS_HOST'=>  '10.8.8.33,10.8.8.34', //分散式Redis,預設第一個為主伺服器

'SESSION_REDIS_PORT'=>  '6379',      //埠,如果相同只填一個,用英文逗號分隔

'SESSION_REDIS_AUTH'    =>  'redis123',    //Redis auth認證(金鑰中不能有逗號),如果相同只填一個,用英文逗號分隔

<?php


namespace Think\Session\Driver;

/**
 * Redis Session驅動 
 * 要求安裝phpredis擴充套件:https://github.com/nicolasff/phpredis
 * @category   Think
 * @package  Session
 * @subpackage  Driver
 * @version   TP3.2~TP3.2.1
  +------------------------------------------------------------------------------
 */
class Redis {
	
	/**
	 * Redis控制代碼
	 */
	private $handler;
	private $get_result;

	public function __construct(){
		if ( !extension_loaded('redis') ) {
            E(L('_NOT_SUPPERT_').':redis');
        }
        if(empty($options)) {
            $options = array (
                'host'          => C('SESSION_REDIS_HOST') ? C('SESSION_REDIS_HOST') : '127.0.0.1',
                'port'          => C('SESSION_REDIS_PORT') ? C('SESSION_REDIS_PORT') : 6379,
                'timeout'       => C('SESSION_CACHE_TIME') ? C('SESSION_CACHE_TIME') : false,
                'persistent'    => C('SESSION_PERSISTENT') ? C('SESSION_PERSISTENT') : false,
				'auth'			=> C('SESSION_REDIS_AUTH') ? C('SESSION_REDIS_AUTH') : false,
            );
        }
		$options['host'] = explode(',', $options['host']);
		$options['port'] = explode(',', $options['port']);
		$options['auth'] = explode(',', $options['auth']);
		foreach ($options['host'] as $key=>$value) {
			if (!isset($options['port'][$key])) {
				$options['port'][$key] = $options['port'][0];
			}
			if (!isset($options['auth'][$key])) {
				$options['auth'][$key] = $options['auth'][0];
			}
		}
        $this->options =  $options;
		$expire = C('SESSION_EXPIRE');
        $this->options['expire'] =  isset($expire) ? (int)$expire : (int)ini_get('session.gc_maxlifetime');;
        $this->options['prefix'] =  isset($options['prefix']) ?  $options['prefix']  :   C('SESSION_PREFIX');
        $this->handler  = new \Redis;
	}

	/**
	 * 連線Redis服務端
	 * @access public
	 * @param bool $is_master : 是否連線主伺服器
	 */
	public function connect($is_master = true) {
		if ($is_master) {
			$i = 0;
		} else {
			$count = count($this->options['host']);
			if ($count == 1) {
				$i = 0;
			} else {
				$i = rand(1, $count - 1);	//多個從伺服器隨機選擇
			}
		}
		$func = $this->options['persistent'] ? 'pconnect' : 'connect';
		try {
			if ($this->options['timeout'] === false) {
				$result = $this->handler->$func($this->options['host'][$i], $this->options['port'][$i]);
				if (!$result)
					throw new \Think\Exception('Redis Error', 100);
			} else {
				$result = $this->handler->$func($this->options['host'][$i], $this->options['port'][$i], $this->options['timeout']);
				if (!$result)
					throw new \Think\Exception('Redis Error', 101);
			}
			if ($this->options['auth'][$i]) {
				$result = $this->handler->auth($this->options['auth'][$i]);
				if (!$result) {
					throw new \Think\Exception('Redis Error', 102);
				}
			}
		} catch ( \Exception $e ) {
			exit('Error Message:'.$e->getMessage().'<br>Error Code:'.$e->getCode().'');
		}
	}
	
	/**
	  +----------------------------------------------------------
	 * 開啟Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $savePath 
	 * @param mixed $sessName  
	  +----------------------------------------------------------
	 */
	public function open($savePath, $sessName) {
		return true;
	}
	
	/**
	  +----------------------------------------------------------
	 * 關閉Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 */
	public function close() {
		if ($this->options['persistent'] == 'pconnect') {
			$this->handler->close();
		}
		return true;
	}

	/**
	  +----------------------------------------------------------
	 * 讀取Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $sessID 
	  +----------------------------------------------------------
	 */
	public function read($sessID) {
		$this->connect(0);
		$this->get_result = $this->handler->get($this->options['prefix'].$sessID);
        return $this->get_result;
	}

	/**
	  +----------------------------------------------------------
	 * 寫入Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $sessID 
	 * @param String $sessData  
	  +----------------------------------------------------------
	 */
	public function write($sessID, $sessData) {
		if (!$sessData || $sessData == $this->get_result) {
			return true;
		}
		$this->connect(1);
        $expire  =  $this->options['expire'];
        $sessID   =   $this->options['prefix'].$sessID;
        if(is_int($expire) && $expire > 0) {
            $result = $this->handler->setex($sessID, $expire, $sessData);
			$re = $result ? 'true' : 'false';
        }else{
            $result = $this->handler->set($sessID, $sessData);
			$re = $result ? 'true' : 'false';
        }
        return $result;
	}

	/**
	  +----------------------------------------------------------
	 * 刪除Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $sessID 
	  +----------------------------------------------------------
	 */
	public function destroy($sessID) {
		$this->connect(1);
        return $this->handler->delete($this->options['prefix'].$sessID);
	}

	/**
	  +----------------------------------------------------------
	 * Session 垃圾回收
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $sessMaxLifeTime 
	  +----------------------------------------------------------
	 */
	public function gc($sessMaxLifeTime) {
		return true;
	}

	/**
	  +----------------------------------------------------------
	 * 開啟Session 
	  +----------------------------------------------------------
	 * @access public 
	  +----------------------------------------------------------
	 * @param string $savePath 
	 * @param mixed $sessName  
	  +----------------------------------------------------------
	 */
	public function execute() {
		session_set_save_handler(
				array(&$this, "open"),
				array(&$this, "close"),
				array(&$this, "read"),
				array(&$this, "write"),
				array(&$this, "destroy"),
				array(&$this, "gc")
		);
	}
	
	public function __destruct() {
		if ($this->options['persistent'] == 'pconnect') {
			$this->handler->close();
		}
		session_write_close();
	}

}