たくさんのデバッグを行った後、問題は(恥ずかしいことに)私のデータベースセッションコードにあり、典型的なセッションの問題ではなかったようです。あなたはここでそれに関連する私の答えを見ることができます-ありがとう
これは同様の質問(たとえば、1、2、3 )の重複である可能性があることを理解していますが、これのベストプラクティスと思われるものに従っているにもかかわらず、まだ問題があります。
session_set_save_handler()を使用してデータベースセッションクラスを使用する場合、session1.phpからリダイレクトされた後、session2.phpでセッションが開始されると、セッションデータがクリアされます。
私の観察の概要:
- データはsession1.phpでデータベースに正しく保存されます
- session2.phpのsession_start()でデータが失われます
- リダイレクト後、session2.phpでsession_start()が呼び出される前に、データはデータベースに残ります。
- セッションIDは同じままで、リクエストヘッダーでサーバーに正しく返送されるCookieに保存されます
- PHPのデフォルトのセッション処理を使用すると、問題なく機能します
そして注意:
- header()の後に使用されるexit()
- 出力前のすべてのページでsession_start()
私はばかげたタイプミスをしましたか?ダフトエラーを起こしましたか?それともこれは奇妙な癖ですか?
提供された助けを事前に感謝します。
コードは次のとおりです(この問題を修正する際にテストファイルに抽出されます):
session1.php
<?php
require_once('session.php');
session_start();
$_SESSION['KEY'] = 'VALUE PHPSESSID: ' . session_id();
session_write_close();
header('Location: session2.php');
exit;
session2.php
<?php
require_once('session.php');
session_start();
// Nothing?
var_dump( $_SESSION );
session.php
<?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')
);
DatabaseSessionHandler.php
<?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;
}
}