興味深い問題に出くわしました。私が取り組んでいるサイトには、現在、login.php、welcome.php、ajax.php の 3 つのページがあります。それらはすべて、コードの先頭で session_start() を呼び出します。Login.php は $_SESSION[] 変数をチェックして、誰かがログインしているかどうかを確認します。そうでない場合は、name/pwd を取得し、ajax.php に連絡して name/pwd を確認し、適切な $_SESSION[] 変数を設定してログインします。Welcome.php は適切な $_SESSION[] 変数を探し、ユーザーにウェルカム メッセージを表示します。設定されていない場合は、ユーザーにログインを求めます。典型的な動作であり、典型的な方法で使用すると完全に機能します。
ただし、login.php とwelcome.php を一連のタブとしてブックマークし (Firefox などで)、両方を同時に開くと、奇妙なことが起こります。おそらく、session_start() がまったく同時に 2 回呼び出されるため (error_log() を使用してチェック)、2 つの別個のセッションが作成されます (session_id() でチェック)。session_start() がたまたま「最後」に呼び出された場合 (タイムスタンプは同じですが) は、残っているセッションです。これは、次のシナリオで問題を引き起こします: login.php の session_start() が、welcome.php の session_start() が呼び出される前に呼び出されます。
この場合、login.php で作成されたセッションは、更新されない限りそのページに存在し続けます。ただし、名前/パスワードの詳細を確認するために ajax.php に接続し、ajax.php が session_start() を呼び出すと、welcome.php によって作成されたセッションが取得されます。不合格。そのため、login.php が最初に session_start() を呼び出す場合、welcome.php の session_start() が新しいセッションを作成しないようにする方法を考え出す必要があります。注: 呼び出し順序は一貫しておらず、login.php の session_start() が最後に呼び出されている限り (これは制御できません)、明らかにすべて正常に機能します。
理想的には、2 番目のファイルが最初のファイルがsession を作成中であることを認識する何らかの方法があるため、独自のファイルを作成しないでください (ただし、welcome.php の場合のみ)。
これは他の人が対処した問題であるに違いありませんが、私はこれらのここのインターウェブでそれについての言及を完全に見つけることができませんでした. どんな助けでも大歓迎です。
EDIT1: 問題を再現するために必要なファイルは次のとおりです。
ログイン.PHP
<?php
session_start();
error_log("login.php, session id: ".session_id());
$_SESSION['user'] = "EleventyOne"
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - login</title>
<script src='jquery-1.9.1.js'></script>
<script>
$(document).ready(function() {
$.ajax({
url : 'ajax.php',
data : { 'func' : 'check_login' },
dataType : 'json',
type : 'GET',
timeout : 10000
})
.done(function(data,textStatus,jqXHR){
alert("Done: "+data.status);
})
.fail(function(jqXHR,textStatus,errorThrown) {
alert("Failed: " + textStatus + "(" + errorThrown + ")");
});
}); // end ready
</script>
</head>
<body>
</body>
</html>
ようこそ.PHP:
<?php
session_start();
error_log("welcome.php, session id: ".session_id());
$message = "";
if ( isset($_SESSION['user']) ) {
$message = "Hello, ".$_SESSION['user'];
}
else {
$message = "Please login!";
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - welcome</title>
</head>
<body>
<div>
<?php echo $message; ?>
</div>
</body>
</html>
AJAX.PHP:
<?php
session_start();
error_log("ajax.php, session id: ".session_id());
// ignoring $_GET[] here, as superfluous to the point...
if ( isset($_SESSION['user']) ) {
// check the database for that user...
// ...
// return status
$ret['status'] = "ok";
echo json_encode($ret);
exit;
}
else {
// return failed status
$ret['status'] = "broken session";
echo json_encode($ret);
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>multiple session bug - ajax</title>
<script src='_js/jquery-1.9.1.js'></script>
<script>
$(document).ready(function() {
}); // end ready
</script>
</head>
<body>
</body>
</html>
login.php をロードし、新しいタブを開き、welcome.php をロードすると、取得される error_log ファイルは次のとおりです (すべて問題ありません)。
[27-Jun-2013 18:39:40 UTC] login.php, session id: skofpr8g0tg81aqohnkahv3vk5
[27-Jun-2013 18:39:40 UTC] ajax.php, session id: skofpr8g0tg81aqohnkahv3vk5
[27-Jun-2013 18:39:44 UTC] welcome.php, session id: skofpr8g0tg81aqohnkahv3vk5
login.php とwelcome.php を一連のタブとしてブックマークし、ブラウザーを閉じてから再度開き、両方のタブを同時に開くと、どちらの session_start が最初に呼び出されたかに応じて、2 つの error_log ファイルのいずれかが取得されます。 .
これは、login.php の session_start() が ajax.php に対して持続するため、機能します。したがって、ajax.php は「ok」のステータスを報告します。
[27-Jun-2013 18:40:39 UTC] welcome.php, session id: 6q2q96lhhoaqqhj214gs3gos36
[27-Jun-2013 18:40:39 UTC] login.php, session id: j8eaa5mtfsla9q3q80qt03kvt7
[27-Jun-2013 18:40:39 UTC] ajax.php, session id: j8eaa5mtfsla9q3q80qt03kvt7
これは、welcome.php の session_start() が ajax.php に対して存続するため、機能しません。
[27-Jun-2013 18:40:18 UTC] login.php, session id: s4b7jo41jpg1ubbe8at7c5qr35
[27-Jun-2013 18:40:18 UTC] welcome.php, session id: freu86sn3edc3fuoc2pn875o90
[27-Jun-2013 18:40:18 UTC] ajax.php, session id: freu86sn3edc3fuoc2pn875o90