【问题标题】:php sessions in database only writing part of information to the table数据库中的php会话仅将部分信息写入表
【发布时间】:2011-02-20 15:57:01
【问题描述】:

更新(添加了读/写类的代码)

<?php
error_reporting(E_ALL);

class dbSession
{
    function dbSession($gc_maxlifetime = "", $gc_probability = "", $gc_divisor = "")
    {
        if ($gc_maxlifetime != "" && is_integer($gc_maxlifetime)) {
            @ini_set('session.gc_maxlifetime', $gc_maxlifetime);
        }
        if ($gc_probability != "" && is_integer($gc_probability)) {
            @ini_set('session.gc_probability', $gc_probability);
        }
        if ($gc_divisor != "" && is_integer($gc_divisor)) {
            @ini_set('session.gc_divisor', $gc_divisor);
        }
        $this->sessionLifetime = ini_get("session.gc_maxlifetime");
        session_write_close(); 

        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');
        @session_start();
    }

    function open($save_path, $session_name)
    {
        $mySQLHost = "localhost";
        $mySQLUsername = "username";
        $mySQLPassword = "password";
        $mySQLDatabase = "rst_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 (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 $fields["session_data"];

        }
        return "";
    }

    function write($session_id, $session_data)
    {

        // first checks if there is a session with this id
        $result = @mysql_query(" SELECT *FROM session_data WHERE session_id = '".$session_id."'");
        if (@mysql_num_rows($result) > 0) 
        {
            $result = @mysql_query(" UPDATE session_data
                SET
                    session_data = '".$session_data."',
                    session_expire = '".(time() + $this->sessionLifetime)."',
                    account_id = '" . $_SESSION['account']['account_id'] . "',
                    username = '" . $_SESSION['users']['username'] . "', 
                    report_logo_path = '". $_SESSION['path_to_report_logo'] . '/' . $_SESSION['report_logo_img'] . "',
                    report_footer_all = '". $_SESSION['report_footer_all'] . "',
                    report_footer_summary= '". $_SESSION['report_footer_summary'] . "'
                WHERE
                    session_id = '".$session_id."'
            ");

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


        } 
        else // if this session id is not in the database
        {
            $sql = "
                INSERT INTO
                    session_data
                        (
                            session_id,
                            http_user_agent,
                            session_data,
                            session_expire,
                            account_id,
                            username
                        )
                    VALUES
                        (
                            '".serialize($session_id)."',
                            '".$_SERVER["HTTP_USER_AGENT"]."',
                            '".$session_data."',
                            '".(time() + $this->sessionLifetime)."',
                            '".$_SESSION['account']['account_id']."',
                            '".$_SESSION['users']['username']."'    
                        )
            ";

            $result = @mysql_query($sql);

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

        }

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

    }

}
?>

更新:我已取消注释 php.ini 文件中的行以允许将会话写入文件而不是数据库,并将 session_start() 放在正确的位置。所以我已经能够排除其他地方的代码。此问题仅在使用数据库存储会话时发生,这是一项要求,因此如果有任何其他想法可以帮助我解决此问题,请告诉我。谢谢。


原帖: 我很难弄清楚这里发生了什么,希望有人能帮助我。

我一直在使用php,mysql将我的会话信息存储在数据库中。该应用程序仅在 localhost、vista 上运行。在 php.ini 文件中,我注释掉了“session.save_handler = files”行,并使用 php 类来处理会话写入/读取等。

我的登录过程是这样的:通过 login.php 提交登录凭据。 login.php 调用 loginprocess.php。 loginprocess.php 验证用户,如果valid 启动一个新会话并将数据添加到会话变量,然后它会重定向到index.php。

这就是问题所在。 loginprocess.php 页面有一堆会话变量,设置为 $_SESSION['account_id'] = $account_id;等等,但是当我转到 index.php 并执行 var_dump($_SESSION) 时,它只会显示“array() empty”。但是,如果我在 loginprocess.php 中执行 var_dump($_SESSION),就在重定向行 header("Location: ../index.php"); 之前,它会显示会话变量中的所有数据。如果我查看存储会话信息的数据库,在 session_id 字段、created_ts 字段和 expires 字段中有数据,但 session_data 字段内部没有任何内容,过去这是我所有会话数据的字段被存储。

我如何能够在 loginprocess.php 中对会话进行 var_dump,但 db 表中不存在数据,是否使用某种缓存?我清除了我的 cookie 等...但没有任何变化。

为什么 session_id 被写入表中,而实际的会话数据却没有?

任何想法都值得赞赏。谢谢。

【问题讨论】:

  • 我们将不得不更多地了解您用于保存会话数据的过程。你说你将它存储在数据库中 - 你的会话读/写处理程序是如何设置的?
  • 我已经用执行读/写的类对象更新了帖子。感谢您的帮助。

标签: php session session-variables


【解决方案1】:

要访问 PHP 上的会话数据,您需要 session_start 之前。

【讨论】:

  • 你的每个页面都需要 session_start
  • 在类中有一个 session_start,每次创建对象时都会实例化。我确保所有页面都有一个实例化对象,但结果仍然相同。
  • 我遇到了在调用 header(location...) 之前填充会话变量的问题。它只是没有用,我正要发疯 - 然后我在 PHP 帮助页面上找到了这个: session_start(); $_SESSION['mySession'] = "你好"; header ("位置:xpage.php");出口(); //这句话有什么魔力?>试试这个,让我们知道。干杯。
  • 感谢 Ronalod,但我无法成功。这是我得到的:“会话已经开始 - 忽略 session_start()”当我将 session_start() 放在 header() 调用之前...这意味着我正在使用的类已正确实例化并启动了会话...不过我快要疯了...对这个真的很沮丧...花了 8 个月的时间在一个几乎准备好进行测试的项目上,现在我什至无法登录,因为我看不到一些小变化。
【解决方案2】:

查看serialize()函数,在写入数据库之前考虑使用它;以及读取时对应的unserialize()

【讨论】:

  • 感谢您的回复。在 write() 函数中,我在 sql 语句中将 $session_data 替换为 serialize($session_data),然后在 read() 函数中,我将 return unserialize($fields["session_data"]) 替换为 return $fields["会话数据"];但还是一样。我是不是放错地方了?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 2012-11-08
相关资源
最近更新 更多