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会话变量在不应该存在的时候存在,在应该存在的时候不存在的主要内容,如果未能解决你的问题,请参考以下文章

仅在不存在时如何创建 terraform 资源

我应该在 CodeIgniter 中使用哪个会话库?

php会话变量的安全性如何[重复]

检测 PHP 会话是不是存在

PHP 中会话名称的限制是啥?

PHP 不能归档contact.html,但它不应该存在? (智能引擎)