如何使用用户定义的函数覆盖session_set_save_handler()?

时间:2014-04-27 22:23:37

标签: php session

我正在尝试将会话保存在数据库中而不是服务器上的文件中。我已经像这样定义了session_set_save_handler()

//Set handler to override SESSION
session_set_save_handler( array($this, "open"),
                          array($this, "close"),
                          array($this,"read"),
                          array($this, "write"),
                          array($this,"destroy"),
                          array($this, "gc"));

但我一直收到这个警告

Undefined variable: this

然后我尝试将其更改为

session_set_save_handler( "open", "close", "read", "write", "destroy", "gc" );

我没有收到错误,但收到以下警告

Warning: session_set_save_handler(): Argument 1 is not a valid callback

这是我的open()函数

static protected function open(){
// If successful return true
if($this->db)
    return true;

return false;
}

我的问题是如何正确覆盖该功能?

这是我的全班

<?php

class SessionManager {
    /**
     * AOL users may switch IP addresses from one proxy to another.
     *
     * @link http://webmaster.info.aol.com/proxyinfo.html
     * @var array
     */
    protected $aolProxies = array('195.93.', '205.188', '198.81.', '207.200', '202.67.', '64.12.9');
    private $db;
    /**
     * This function starts, validates and secures a session.
     *
     * @param string $name The name of the session.
     * @param int $limit Expiration date of the session cookie, 0 for session only
     * @param string $path Used to restrict where the browser sends the cookie
     * @param string $domain Used to allow subdomains access to the cookie
     * @param bool $secure If true the browser only sends the cookie over https
     */
    static function sessionStart($dbo, $name, $limit = 0, $path = '/', $domain = null, $secure = null)
    {
        $this->db = $dbo;

        //Set the cookie name
        session_name($name);  //. '_Session'

        //Set SSL level
        $https = isset($secure) ? $secure : isset($_SERVER['HTTPS']);

        //Set session cookie options
        session_set_cookie_params($limit, $path, $domain, $https, true);

        //Set handler to override SESSION
        session_set_save_handler( "open", "close", "read", "write", "destroy", "gc" );

        session_start();

        // Make sure the session hasn't expired, and destroy it if it has
        if(self::validateSession()){
            // Check to see if the session is new or a hijacking attempt
            if(!self::preventHijacking()){
                // Reset session data and regenerate id
                $_SESSION = array();
                $_SESSION['IPaddress'] = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
                $_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
                self::regenerateSession();

            // Give a 5% chance of the session id changing on any request
            } elseif(rand(1, 100) <= 5)
                self::regenerateSession();

        } else {
            $_SESSION = array();
            session_destroy();
            session_start();
        }
    }

    /*
     * This function regenerates a new ID and invalidates the old session. This should be called whenever permission
     * levels for a user change.
     */
    static function regenerateSession(){
        // If this session is obsolete it means there already is a new id
        if(isset($_SESSION['OBSOLETE']) || $_SESSION['OBSOLETE'] == true)
            return;

        // Set current session to expire in 10 seconds
        $_SESSION['OBSOLETE'] = true;
        $_SESSION['EXPIRES'] = time() + 10;

        // Create new session without destroying the old one
        session_regenerate_id(false);

        // Grab current session ID and close both sessions to allow other scripts to use them
        $newSession = session_id();
        session_write_close();

        // Set session ID to the new one, and start it back up again
        session_id($newSession);
        session_start();

        // Now we unset the obsolete and expiration values for the session we want to keep
        unset($_SESSION['OBSOLETE']);
        unset($_SESSION['EXPIRES']);
    }

    /*
     * This function is used to see if a session has expired or not.
     * @return bool
     */
    static protected function validateSession(){
        if( isset($_SESSION['OBSOLETE']) && !isset($_SESSION['EXPIRES']) )
            return false;

        if(isset($_SESSION['EXPIRES']) && $_SESSION['EXPIRES'] < time())
            return false;

        return true;
    }

    /*
     * This function checks to make sure a session exists and is coming from the proper host. On new visits and hacking
     * attempts this function will return false.
     *
     * @return bool
     */
    static protected function preventHijacking(){
        if(!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent']))
            return false;


        if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT']
            && !( strpos($_SESSION['userAgent'], 'Trident') !== false
                && strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false))
            return false;


        $sessionIpSegment = substr($_SESSION['IPaddress'], 0, 7);

        $remoteIpHeader = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];

        $remoteIpSegment = substr($remoteIpHeader, 0, 7);

        if($_SESSION['IPaddress'] != $remoteIpHeader
            && !(in_array($sessionIpSegment, $this->aolProxies) && in_array($remoteIpSegment, $this->aolProxies)))

            return false;


        if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT'])
            return false;

        return true;
    }

    //Open the database connection
    private function open(){
        // If successful return true
        if($this->db)
            return true;

        return false;
    }

     //Close the database connection
    static protected function close(){
        // If successful return true
        if($this->db->endConnection())
            return true;

        return false;
    }

    //Read the session information
    private function read($id){
        //Select session data
        $info = $this->db->getOneResult('SELECT data FROM sessions WHERE id = ?', array($id) );

        //if data found return it
        if($info)
            return $info['data'];

        // Return an empty string
        return '';
    }


    //Write the session information
    private function write($id, $data){
        // Create time stamp
        $access = time();

        // Set query  
        $write = $this->db->processQuery('REPLACE INTO sessions VALUES (?, ?, ?)', array($id, $access, $data));

        // If successful return true
        if($write)
            return true;

        // Return False
        return false;
    }


    //Destroy
    private destroy($id){
        //Delete record
        $delete = $this->db->processQuery('DELETE FROM sessions WHERE id = ?',array($id) );

        // Attempt execution
        // If destroyed return true
        if( $delete )
            return true;

        // Return False
        return false;
    } 


    //Garbage Collection
    private function gc($max){
        // Calculate what is to be deemed old
        $old = time() - $max;

        //Delete old sessions
        $delete = $this->db->processQuery('DELETE FROM sessions WHERE access < ?', array($old));

        //if Garbage has been removed return true
        if($delete)
            return true;

      // Return False
      return false;
    }

}

?>

2 个答案:

答案 0 :(得分:1)

您是在静态方法中定义它。静态方法中不存在$this

您可以使用类名本身。所以你会做类似的事情:

//Set handler to override SESSION
session_set_save_handler( array("SessionManager", "open"),
                          array("SessionManager", "close"),
                          ....);

答案 1 :(得分:-3)

尝试使用此表单"@"

@session_set_save_handler(
          array($this, "_open"),
          array($this, "_close"),
          array($this, "_read"),
          array($this, "_write"),
          array($this, "_destroy"),
          array($this, "_gc")
        );