Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 页面重定向后在会话_start()上删除的会话数据_Php_Mysql - Fatal编程技术网

Php 页面重定向后在会话_start()上删除的会话数据

Php 页面重定向后在会话_start()上删除的会话数据,php,mysql,Php,Mysql,经过大量调试后,问题似乎(令人尴尬地)出现在我的数据库会话代码中,而不是典型的会话问题。你可以看到我的答案与之相关-谢谢 我知道这可能是类似问题的重复(例如),但尽管遵循了这方面的最佳实践,我仍然有问题 当使用session_set_save_handler()使用我的数据库会话类时,当会话从session1.php重定向到session2.php时,会话数据将被清除 我的意见概述: 数据在session1.php中正确保存到数据库中 session2.php中会话_start()上的数据丢

经过大量调试后,问题似乎(令人尴尬地)出现在我的数据库会话代码中,而不是典型的会话问题。你可以看到我的答案与之相关-谢谢


我知道这可能是类似问题的重复(例如),但尽管遵循了这方面的最佳实践,我仍然有问题

当使用session_set_save_handler()使用我的数据库会话类时,当会话从session1.php重定向到session2.php时,会话数据将被清除

我的意见概述:

  • 数据在session1.php中正确保存到数据库中
  • session2.php中会话_start()上的数据丢失
  • 在重定向之后以及在session2.php中调用会话_start()之前,数据仍在数据库中
  • 会话ID保持不变,并存储在一个cookie中,该cookie将被正确地发送回请求头中的服务器
  • 使用PHP的默认会话处理,它可以正常工作
并请注意:

  • 在header()之后使用exit()
  • 输出前每页上的会话_start()
我有没有搞错?犯了愚蠢的错误?或者这是一个奇怪的怪癖

提前感谢您提供的任何帮助

以下是代码(在修复此问题时提取到测试文件中):

session1.php

<?php

require_once('session.php');

session_start();  

$_SESSION['KEY'] = 'VALUE PHPSESSID: ' . session_id();

session_write_close();   
header('Location: session2.php');
exit;
<?php

require_once('session.php');

session_start();

// Nothing?
var_dump( $_SESSION );
<?php

define( "DB_HOST", 'localhost' );
define( "DB_USER", '******' );
define( "DB_PWD", '******' );
define( "DB_NAME", '******' );

require_once('class/DatabaseSessionHandler.php');

// Use the DatabaseSessionHandler class to handle sessions
$session_handler = new DatabaseSessionHandler;
// Set up the handler above as the default session handler
session_set_save_handler(
    array($session_handler, 'open'),
    array($session_handler, 'close'),
    array($session_handler, 'read'),
    array($session_handler, 'write'),
    array($session_handler, 'destroy'),
    array($session_handler, 'gc')
);
<?php

class DatabaseSessionHandler
{

    protected $connection;
    protected $session_life_time;

    public function __construct()
    {
        // Ensure that everything is closed correctly as 
        // per warning on http://uk3.php.net/session_set_save_handler
        register_shutdown_function( 'session_write_close' );
    }

    public function open( $save_path, $session_name )
    {
        $this->connection = new mysqli( DB_HOST, DB_USER, DB_PWD, DB_NAME );
        $this->session_life_time = get_cfg_var( "session.gc_maxlifetime" );

        if ( $this->connection->connect_error )
            return false;

        return true;
    }

    public function close()
    {
        $this->connection->close();
        return true;
    }

    public function read( $session_id )
    {
        $data = '';

        $statement = $this->connection->prepare( "SELECT `session_data` 
                                                  FROM `session` 
                                                  WHERE `session_id` = ? " );
        $statement->bind_param( "s", $session_id );
        $statement->execute();
        $statement->bind_result( $data );

        return (string) $data;
    }

    public function write( $session_id, $session_data )
    {
        $expiry_time = time() + $this->session_life_time;
        $statement = $this->connection->prepare( "REPLACE INTO `session` 
                                                (`session_id`, `session_data`, 
                                                `expiry_time`)
                                                 VALUES (?, ?, ?)" );
        $statement->bind_param( "ssi", $session_id, $session_data, $expiry_time );

        if ( !$statement->execute() )
            return false;

        return true;
    }

    public function destroy( $session_id )
    {
        $statement = $this->connection->prepare( "DELETE FROM `session` 
                                                    WHERE `session_id` = ?" );
        $statement->bind_param( "s", $session_id );

        if ( !$statement->execute() )
            return false;

        return true;
    }

    public function gc( $max_lifetime )
    {
        $current_time = time();
        $statement = $this->connection->prepare( "DELETE FROM `session` 
                                                    WHERE `expiry_time` < ?" );
        $statement->bind_param( "i", $current_time );

        if ( !$statement->execute() )
            return false;

        return true;
    }

}

您正在清除会话数据,时间少于当前时间。它应该是当前时间-最大使用寿命

这是解决办法

public function gc( $max_lifetime )
{
    $current_time = time() - $max_lifetime;
    $statement = $this->connection->prepare( "DELETE FROM `session` 
                                                    WHERE `expiry_time` < ?" );
    $statement->bind_param( "i", $current_time );

    if ( !$statement->execute() )
            return false;

    return true;
}
公共函数gc($max_life)
{
$current_time=time()-$max_life;
$statement=$this->connection->prepare(“从'session'删除”
其中“到期时间”<?”;
$statement->bind_参数(“i”,$current_time);
如果(!$statement->execute())
返回false;
返回true;
}

在大量记录文件和打印变量(一些会话函数在发送到浏览器的输出后调用,因此不能以正常方式输出错误)之后,问题在于我的数据库会话代码

在将MySQLi输出绑定到一个变量之后,我忘记添加“$statement->fetch()”,因此我从未真正从数据库中获取数据

这是一个令人尴尬的错误,但它让我们明白了这样一个事实:如果你的软件出现了问题,那么这往往是你的代码中的问题,而不是你正在使用的语言或库中的问题


感谢那些评论和回答我的人,在过去的几天里,我学到了很多关于PHP会话的知识。

在destroy中记录一些东西,在gc中记录一些东西,这样你就知道哪一个应该被删除。或者使用调试器。如果不使用
会话_write_close()?另外,您在哪台服务器上运行此功能?查看此问题(请参见回答中的注释)@GeraldVersluis重定向后数据仍在数据库中,因此它不是session\u write\u close()函数(尝试删除它,但仍然没有成功)@GregFire似乎两个都没有被调用,因此它们不是罪魁祸首。@GeraldVersluis我忘记添加,这是在Apache2.2.17(Windows)上使用PHP5.3.5运行的,尽管它最终会在Linux服务器上运行(虽然还没有测试)。啊,这是一个我忽略了的问题,但似乎不是问题。即使没有调用垃圾收集器,问题也会发生。我很感激你纠正这一点,因为如果不是这样的话,它很可能会被错过。