PHP实现预留SessionHandlerInterface接口从而将session存储到数据库中

session在开发web应用中可谓是相当重要,php为session提供了三种存储方式:文件、内存、自定义存储,默认是使用文件存储。

这里我们通过php提供的session_set_save_handler()函数来重写session,从而将session存储到数据库中。

注释:session_set_save_handler()设置用户自定义 会话存储函数。 如果想使用 PHP 内置的会话存储机制之外的方式, 可以使用本函数。 例如,可以自定义会话存储函数来将会话数据存储到数据库。

PHP5.4以后支持了SessionHandlerInterface接口。

SessionHandlerInterface {
    /* 抽象方法 */
    abstract public bool close ( void )
    abstract public bool destroy ( string $session_id )
    abstract public bool gc ( int $maxlifetime )
    abstract public bool open ( string $save_path , string $name )
    abstract public string read ( string $session_id )
    abstract public bool write ( string $session_id , string $session_data )
}

我们需要做的就是实现这个接口里所有的方法,然后通过session_set_save_hander() 函数来使方法生效。

class Session_Handler_To_DB implements SessionHandlerInterface{

    //会话生命周期
    protected $_lifetime='7200';

    //session table
    protected $_table='';

    /**
     * 构造函数
     * @param   arrSettings array 配置参数[可选]
     */
    function __construct($arrSettings=array()){
        if(is_numeric($arrSettings['lifetime'])) $this->_lifetime=$arrSettings['lifetime'];
    }

    /**
     * SESSION打开
     * @param   save_path   string 保存路径
     * @param   session_name string 会话id
     * @return  boolean 是否成功
     */
    public function open($savePath, $sessionName){
        return true;
    }

    /**
     * SESSION关闭
     * @return  boolean
     */
    public function close(){
        return true;
    }

    /**
     * 读取SESSION信息并验证是否有效
     * @param   key string session的key值
     * @return  mixed
     */
    public function read($key){
        try {
            $db = GetDB();
            $current_time = time();
            /* 首先删除当前key下已经过期的session*/
            //$db->Query('DELETE FROM '.$this->_table.' WHERE SESS_KEY=? AND EXPIRY_DATE<?', array($key, $current_time));
            /*查询当前key下未超时的Session*/
            $query = $db->Query("SELECT SESS_VALUE FROM ".$this->_table.' WHERE SESS_KEY=? AND EXPIRY_DATE >=?', array($key, $current_time));
            /*返回结果SESS_VALUE*/
            if(is_array($query) && count($query)>0){
                return $query[0]['SESS_VALUE'];
            }else return false;

        } catch (CO_DB_Exception $e) {
            //接收数据库异常
            return false;
        }
    }

    /**
     * 写入SESSION信息
     * @param   key string session的key值
     * @param   val string session数值
     * @return  boolean
     */
    public function write($key, $val){
        try {
            $db = GetDB();
            //获取远程操作IP
            $ip = bindec(decbin(ip2long($_SERVER['REMOTE_ADDR'])));
            $current_time = time();
            /* 刷新过期时间,并插入session记录*/
            $new_expriy = $current_time + $this->_lifetime;
            if($db->Select($this->_table, array('SESS_KEY' => $key), array('select'=>array(SESS_KEY))) === false){
                $ins = $db->Insert($this->_table, array(
                        "SESS_KEY"=>$key,
                        "SESS_VALUE"=>$val,
                        "EXPIRY_DATE"=>$new_expriy,
                        "LOGIN_IP"=>$ip
                ));
            }else{
                //如果session已经存在,只更新过期时间
                $ins = $db->Query('UPDATE '.$this->_table.' SET `EXPIRY_DATE`=?, `SESS_VALUE`=?, `LOGIN_IP`=? WHERE `SESS_KEY`=?', array($new_expriy, $val, $ip, $key));
            }
            return $ins===false?false:true;
        } catch (Exception $e) {
            //接收数据库异常
            return false;
        }
    }

    /**
     * 删除Session信息
     * @param   key string Session的key值
     * @return  boolean
     */
    public function destroy($key){
        try {
            $db=GetDB();
            $db->Delete($this->_table, array('SESS_KEY'=>$key));
            return true;
        } catch (Exception $e) {
            //接收数据库异常
            return false;
        }
    }

    /**
     * 回收超时SESSION信息
     * @param
     * @return boolean
     */
    public function gc($maxlifetime){
        try {
            $db=GetDB();
            $db->Query('DELETE FROM '.$this->_table.' WHERE `EXPIRY_DATE`<?', array(time()));
        } catch (Exception $e) {
            //接收数据库异常
        }
        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/zyddj123/article/details/78906530
今日推荐