douyi2798 2010-06-18 01:58
浏览 57
已采纳

使用php在mysql中存储会话数据不能正确地从表中检索数据

I have a problem retrieving some data from the $_SESSION using php and mysql. I've commented out the line in php.ini that tells the server to use the "file" to store the session info so my database will be used. I have a class that I use to write the information to the database and its working fine. When the user passes their credentials the class gets instantiated and the $_SESSION vars get set, then the user gets redirected to the index page. The index.php page includes the file where the db session class is, which when instantiated calles session_start() and the session variables should be in $_SESSION, but when I do var_dump($_SESSION) there is nothing in the array. However, when I look at the data in mysql, all the session information is in there. Its acting like session_start() has not been called, but by instantiating the class it is.

Any idea what could be wrong?

Here's the HTML:

<?php 

    include_once "classes/phpsessions_db/class.dbsession.php"; //used for sessions
    var_dump($_SESSION);
?>
<html>
.
.
.
</html>

Here's the dbsession class:

<?php

error_reporting(E_ALL);

class dbSession
{

    function dbSession($gc_maxlifetime = "", $gc_probability = "", $gc_divisor = "")
    {
        // if $gc_maxlifetime is specified and is an integer number
        if ($gc_maxlifetime != "" && is_integer($gc_maxlifetime)) {

            // set the new value
            @ini_set('session.gc_maxlifetime', $gc_maxlifetime);

        }

        // if $gc_probability is specified and is an integer number
        if ($gc_probability != "" && is_integer($gc_probability)) {

            // set the new value
            @ini_set('session.gc_probability', $gc_probability);

        }

        // if $gc_divisor is specified and is an integer number
        if ($gc_divisor != "" && is_integer($gc_divisor)) {

            // set the new value
            @ini_set('session.gc_divisor', $gc_divisor);

        }

        // get session lifetime
        $this->sessionLifetime = ini_get("session.gc_maxlifetime");

        //Added by AARON. cancel the session's auto start,important, without this the session var's don't show up on next pg.
        session_write_close(); 

        // register the new handler
        session_set_save_handler(
            array(&$this, 'open'),
            array(&$this, 'close'),
            array(&$this, 'read'),
            array(&$this, 'write'),
            array(&$this, 'destroy'),
            array(&$this, 'gc')
        );

        register_shutdown_function('session_write_close');

        // start the session
        @session_start();
    }

    function stop()
    {       
        $new_sess_id = $this->regenerate_id(true);
        session_unset();
        session_destroy();

        return $new_sess_id;
    }

    function regenerate_id($return_val=false)
    {
        // saves the old session's id
        $oldSessionID = session_id();
        // regenerates the id
        // this function will create a new session, with a new id and containing the data from the old session
        // but will not delete the old session
        session_regenerate_id();

        // because the session_regenerate_id() function does not delete the old session,
        // we have to delete it manually
        //$this->destroy($oldSessionID);

        //ADDED by aaron
        // returns the new session id
        if($return_val)
        {   
            return session_id();
        }
    }

    function open($save_path, $session_name)
    {
        // global $gf;
        // $gf->debug_this($gf, "GF: Opening Session");
        // change the next values to match the setting of your mySQL database
        $mySQLHost = "localhost";
        $mySQLUsername = "user";
        $mySQLPassword = "pass";
        $mySQLDatabase = "sessions";

        $link = mysql_connect($mySQLHost, $mySQLUsername, $mySQLPassword);

        if (!$link) {

            die ("Could not connect to database!");

        }

        $dbc = mysql_select_db($mySQLDatabase, $link);

        if (!$dbc) {

            die ("Could not select database!");

        }

        return true;

    }

    function close()
    {
        mysql_close();
        return true;
    }

    function read($session_id)
    {

        $result = @mysql_query("
            SELECT
                session_data
            FROM
                session_data
            WHERE
                session_id = '".$session_id."' AND
                http_user_agent = '".$_SERVER["HTTP_USER_AGENT"]."' AND
                session_expire > '".time()."'
        ");

        // if anything was found

        if (is_resource($result) && @mysql_num_rows($result) > 0) {

            // return found data
            $fields = @mysql_fetch_assoc($result);
            // don't bother with the unserialization - PHP handles this automatically
            return unserialize($fields["session_data"]);

        }

        // if there was an error return an empty string - this HAS to be an empty string
        return "";

    }

    function write($session_id, $session_data)
    {
        // global $gf;

        // first checks if there is a session with this id
        $result = @mysql_query("
            SELECT
                *
            FROM
                session_data
            WHERE
                session_id = '".$session_id."'
        ");

        // if there is
        if (@mysql_num_rows($result) > 0) 
        {
            // update the existing session's data
            // and set new expiry time
            $result = @mysql_query("
                UPDATE
                    session_data
                SET
                    session_data = '".serialize($session_data)."',
                    session_expire = '".(time() + $this->sessionLifetime)."'
                WHERE
                    session_id = '".$session_id."'
            ");

            // if anything happened
            if (@mysql_affected_rows()) 
            {
                // return true
                return true;
            }


        } 
        else // if this session id is not in the database
        {
            // $gf->debug_this($gf, "inside dbSession, trying to write to db because session id was NOT in db");
            $sql = "
                INSERT INTO
                    session_data
                        (
                            session_id,
                            http_user_agent,
                            session_data,
                            session_expire
                        )
                    VALUES
                        (
                            '".serialize($session_id)."',
                            '".$_SERVER["HTTP_USER_AGENT"]."',
                            '".$session_data."',
                            '".(time() + $this->sessionLifetime)."'
                        )
            ";

            // insert a new record
            $result = @mysql_query($sql);

            // if anything happened
            if (@mysql_affected_rows()) 
            {
                // return an empty string
                return "";
            }

        }

        // if something went wrong, return false
        return false;

    }

    function destroy($session_id)
    {

        // deletes the current session id from the database
        $result = @mysql_query("
            DELETE FROM
                session_data
            WHERE
                session_id = '".$session_id."'
        ");

        // if anything happened
        if (@mysql_affected_rows()) {

            // return true
            return true;

        }

        // if something went wrong, return false
        return false;

    }

    function gc($maxlifetime)
    {

        // it deletes expired sessions from database
        $result = @mysql_query("
            DELETE FROM
                session_data
            WHERE
                session_expire < '".(time() - $maxlifetime)."'
        ");

    }

} //End of Class

    $session = new dbsession();

?>
  • 写回答

2条回答 默认 最新

  • dqssst0144 2010-06-18 08:16
    关注

    I suspect the reason its not working would be clear if your error reporting was working correctly.

    You're not escaping the session data, and should NOT be serializing the ID. Coincidentally, your code is messy, badly documented and inefficient - e.g. you don't need to see if you already have data then choose to do an insert or update:

    $sql = "REPLACE INTO
                    session_data
                        (
                            session_id,
                            http_user_agent,
                            session_data,
                            session_expire
                        )
                    VALUES
                        (
                            '".mysql_real_escape_string($session_id))."',
                            '".mysql_real_escape_string($_SERVER["HTTP_USER_AGENT"])."',
                            '".mysql_real_escape_string($session_data)."',
                            '".(time() + $this->sessionLifetime)."'
                        )
    

    and....

    // don't bother with the unserialization - PHP handles this automatically
            return unserialize($fields["session_data"]);
    

    (!) Like your comment says - don't try to unserialize the data in the handler.

    C.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥15 MCNP里如何定义多个源?
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器