PHP会话变量在不应该存在的时候存在,在应该存在的时候不存在
Posted
技术标签:
【中文标题】PHP会话变量在不应该存在的时候存在,在应该存在的时候不存在【英文标题】:PHP session variable existing when it shouldn't and not existing when it should 【发布时间】:2020-02-17 14:48:07 【问题描述】:我正在自己的学习项目中寻找乐趣,并且在过去的几周里一直在碰壁。我有会话变量,但它们应该不存在,反之亦然。
在 "example.com/dashboard" 上,$_SESSION['user']
存在,然后在转到 "example.com/app/list" 时,会进行 if 语句测试,如果它确实存在并且已设置。
<?php
session_start();
if(!isset($_SESSION['user']))
$_SESSION['errorMessage'] = "You are not logged in yet!";
header('Location: /');
exit;
即使我验证了在 example.com/dashboard 上设置了 $_SESSION['user']
,if 语句返回 false 并将我带到登录页面。
*在我的例子中,登录页面是我网站根目录上的 index.php。
现在,如果设置了$_SESSION['user']
,您应该会在此登录页面上立即重定向到仪表板。
<?php
session_start();
if(isset($_SESSION['user']))
header('Location: /dashboard');
exit();
就像我之前说的,它已经设置好了,但不知何故没有。刷新时,它会将我发送到仪表板(如果设置了$_SESSION['user']
,则应该会发生这种情况。)
这是问题一。
现在在“example.com/register”上,虽然没有登录(会话在注销时使用 session_unset、session_destroy 等销毁),$_SESSION['user']
不存在。按下提交后,不知何故,$_SESSION['user']
被设置为您登录时的样子。除了登录脚本之外,绝对没有其他任何地方有一段代码可以将$_SESSION['user']
设置为任何东西。我的注册页面上没有任何内容允许这样做。好像注销后会话被保留。
来自我的根页面的代码,即登录表单 (index.php
):
<?php
session_start();
if(isset($_SESSION['user']))
header('Location: /dashboard');
exit();
来自dashboard.php
的代码:
<?php
session_start();
if(!isset($_SESSION['user']))
$_SESSION['errorMessage'] = "You are not logged in yet!";
header('Location: /');
exit;
来自我的logout.php
的代码(因为它可能与此有关):
<?php
session_start();
if(!isset($_SESSION['user']))
$_SESSION['errorMessage'] = "You are not logged in yet!";
header("Location: ../");
die();
//clear session from globals
$_SESSION = array();
session_unset();
session_destroy();
unset($_SESSION);
header("Location: ../");
die;
在我的register.php
:
<?php
session_start();
//register stuff ^^^^^
//eventually, mail to registerer
if (mail($to, $subject, $htmlContent, $headers))
$connect->query($sqlInsert);
$_SESSION['register_success'] = true;
header("Location: https://example.com/register-success");
exit;
然后在我的register-success.php
:
session_start();
if(!isset($_SESSION['register_success']))
$_SESSION['errorMessage'] = "An error has occured, please try again.";
header("Location: https://example.com/register");
exit;
请记住,每当我提交注册时,我都会收到电子邮件,因此应该设置 $_SESSION['register_success']
,但仍然会在“example.com/register-success”上的 if 语句中抛出错误
我尝试过的事情:
session_start();
在每个脚本的开头。
session_destroy()
, session_unset()
, $_SESSION = array()
,
unset($_SESSION)
在注销时,然后是所有这些的组合。
检查所有会话变量名是否匹配,我已经确定了
去做。
我完全不知道为什么会这样。
如果我解释得很糟糕,请提前道歉。
感谢您的阅读。
【问题讨论】:
您的问题+代码很难理解。您能否编辑您的问题,并使用匹配的文本描述标记您的代码 sn-ps。例如,您说,“当转到“example.com/app/list”时......”但我看不到 sn-p 指的是哪个代码。另一个例子,“它返回 false 并把我扔到登录页面......”但你没有显示任何与登录页面相关的代码。 感谢您的评论!我已经编辑了,我希望它至少更清楚一点! 您能告诉我们您的dashboard
页面的会话代码吗?另外,您能否验证register.php
正在启动会话?这可能只是一个复制/粘贴错误,但我在您粘贴的代码中没有看到它。
抱歉,已添加!我还验证了每个页面都有 session_start(),这是我自己尝试修复它时想到的第一件事。
我看不出任何明显的东西可以解释这一点。一个建议是删除注销脚本中的整个 if
语句。由于您在其他脚本中特别遇到了 user
会话变量的问题,我会在注销脚本中消除这种可能性。
【参考方案1】:
我会在注销页面上说,它不应该检查是否设置了用户的会话而不是未设置吗?另外,我会像这样在里面写 session_destroy。此代码检查用户会话变量是否存在,然后它将销毁会话。然后错误消息应该放在 session_start(); 之后重定向到的下一页上。我也不认为除了 session_destroy() 之外你不需要任何东西来销毁会话。
<?php
session_start();
if(isset($_SESSION['user']))
//clear session from globals
session_destroy();
/* Added a Parameter */
header("Location: ../?disperror=1");
else
header("Location: ../");
我不确定这个 errorMessage 是否会正确设置。您可能必须拥有 session_start();在 ../ 页面重定向到该页面时,然后在 session_start 之后设置 errorMessage 会话变量。将其放在 ../ 页面上 session_start() 之后;
<?php
/* Should go on the Login page */
session_start();
/* Request the parameter */
$disperror = $_REQUEST['disperror'];
/* Establish Error Message */
$errMsg = "You are not logged in yet!";
/* Display this anywhere you want in PHP */
if ($disperror == 1)
echo '<p>' . $errMsg . '</p>';
/* If you want to turn that into a session variable only if the session was destroyed */
$_SESSION['errorMessage'] = $errMsg;
?>
【讨论】:
我做了一些更新。如果您要销毁会话,我认为不会设置会话变量。这必须在下一页完成。 感谢您的回答!我将如何决定是否应该显示$_SESSION['errorMessage']
?我现在通过注销页面上的条件来检查用户是否存在,如果不存在则设置错误消息,然后显示在登录页面上。
我做了一些更新。我没有为错误消息使用会话变量,而是使用了一个参数来附加到重定向。然后在登录页面,我请求了那个参数,然后你可以用它来决定是否显示消息。
感谢您的意见,我从没想过以这种方式处理错误消息。我会记住这一点,我一定会尝试一下。以上是关于PHP会话变量在不应该存在的时候存在,在应该存在的时候不存在的主要内容,如果未能解决你的问题,请参考以下文章