【问题标题】:PHP: session isn't saving before header redirectPHP:在标头重定向之前会话未保存
【发布时间】:2011-02-27 11:10:43
【问题描述】:

我已经阅读了这个问题的 php 手册,这似乎是一个很常见的问题,但我还没有找到解决方案。我正在将会话保存在数据库中。 我的代码如下:

// session
$_SESSION['userID'] = $user->id;        
header('Location: /subdirectory/index.php');

然后在 index.php 的顶部 session_start() 之后,我已经 var_dumped 全局 $_SESSION 并且用户 ID 不在其中。正如我所说,我查看了 PHP 手册 (http://php.net/manual/en/function.session-write-close.php),session_write_close 或 session_regenerate_id(true) 都没有为我工作。 有人知道解决方案吗?

编辑:我的文件顶部有 session_start()。当我在标头重定向之前对会话全局进行 var_dump 时,我在其中看到了用户 ID,但在另一个文件中没有,该文件位于此脚本的子目录中

【问题讨论】:

  • 你在 session_starting() 进行重定向吗?
  • 你确定 $user->id 设置了吗?
  • 您好,请查看我为@ahmet2106 的帖子留下的评论
  • 什么是 register_globals 状态?

标签: php session header sessionid


【解决方案1】:

我知道这是一个老话题,但我找到了解决方案(对我来说)。 我在标题后面放了一个出口。

$_SESSION['session'] = 'this is a session';
header('location: apage.php');
exit;

这对我有用

【讨论】:

  • 它只适用于同一个目录。如何为子目录做这项工作? F.e.: 从 http:/domain.com 到 http:/domain.com/subdir/ ?
【解决方案2】:

@Matt(还不能发表评论...):如果:
a) 它出现在重定向之前的会话中
b)其他键工作

80% 的时间问题是 register_globals,并且在某处使用了同名变量 $userID(另外 19% 只是在不期望的地方覆盖,1% 无法在重定向之前写入/锁定会话和陈旧的数据,在这种情况下,您可以在重定向之前尝试 session_write_close())。不用说 register_globals 应该关闭:P

【讨论】:

  • 3 年后。 session_write_close 是今天最好的评论!
【解决方案3】:

我没有听说过这个问题,但我没有太多使用会话。

对于会话,您必须做一些事情并进行一些设置:

  • 在客户端启用 cookie
  • session_start(),在任何事情发生之前
  • 确保您不会破坏会话(除非他们想注销)
  • PHP 会话 ID 必须相同(与 cookie 有关)

另一个问题可能是 $user->id 正在返回对下一页上不存在的对象的引用。很可能不会,但请确保。

如果我看到您的代码,我可以为您提供更多帮助。但是在调试时使用 session_id() 检查会话密钥并确保它是相同的。如果您可以尝试,请告诉我我可以继续提供帮助。

我也想知道当我重新参加会议时这会如何结束。

【讨论】:

    【解决方案4】:

    您应该在使用会话数组之前启动会话。

    PHP 代码,
    session_start();
    $_SESSION['userID'] = $user->id;

    header('位置:/subdirectory/index.php');

    【讨论】:

      【解决方案5】:

      你有没有 session_start();在上面?

      未经测试,但您不能这样做:

      session_start();
      $_SESSION['userID'] = $user->id;
      if( $_SESSION['userID'] == $user->id )
      {  
          header('Location: /index.php');
      }
      

      我从来没有遇到过这个问题,很有趣

      【讨论】:

      • 是的,我愿意。当我在标头重定向之前 var_dump 会话全局时,它就在那里,只是当我转到原始脚本的子文件夹中的新文件时才不是
      • @Matt 很有趣,但它真的很有趣,因为应该设置会话,也许任何其他代码正在删除你的会话,你确定没有其他地方是 session_destroy(); ?
      • 奇怪,我将 $_SESSION['userID'] 更改为 $_SESSION['uid'] 并且它按预期工作。我不知道为什么两个大写字母会有所不同。我也用 userId 尝试过,这也很好。关于它为什么不接受用户 ID 的任何想法?有两个大写字母,我很困惑
      【解决方案6】:

      userID 没有任何关键字状态。

      对我来说唯一的原因是 $_SESSION['userID'] 在某处被覆盖或删除。

      确保在要添加/访问会话的所有文件中使用 session->start()。

      一件重要的事情(可能不适用于您的情况)是,如果使用 cookie 处理会话,则可以使 cookie 只能在某些目录和该目录下的子目录下访问。 无论如何,在您的情况下,子目录将有权访问会话。

      【讨论】:

        【解决方案7】:

        确保两个页面是相同的php版本 (php5、php4有时会话路径不同)

        【讨论】:

          【解决方案8】:

          我最近遇到了同样的问题。我正在为学校编写一个定制的 MVC 网站,正如大家所说,start_session() 必须在第一行代码中编写。

          我的问题是“session_start()”的位置。它必须是全局控制器的第一行,而不是视图的第一行。 $_SESSION 在控制器的文件中不可访问,因为它仅在服务器渲染视图时启动。

          然后,我在 header('location: xxx.php') 调用之后使用 session_write_close() 来为下一个请求保留会话变量。

          例如:

          globalController.php:

          //First line
          session_start();
          require_once('Model/Database.php');
          require_once('Model/Shop/Client.php');
          ...
          

          logonController.php:

          ...
          //Users is validated and redirected.
          $_SESSION['client'] = $client;
          header('location: index.php');
          session_write_close();
          

          希望它能解决你的问题。

          【讨论】:

            【解决方案9】:

            这很烦人,但我终于找到了解决办法。

            config.php 我有: 包括'session.php';

            在 session.php 的顶部,我有: session_start();

            通过将 session_start() 移动到 config.php 文件的顶部,viola...

            问题解决了!

            【讨论】:

            • 您已经解决了这个问题,真是太好了。我只是建议你在你的解决方案中更干净一点,这样它也能帮助其他读者。
            【解决方案10】:

            除了使用exit 强制终止脚本之外,另一种选择是使用session_write_close 强制将更改写入会话存储。

            但是,如果您的脚本正确终止,则不会发生这种情况。

            As the documentation about session_write_close states:

            结束当前会话并存储会话数据。

            会话数据通常在脚本终止后存储 需要调用 session_write_close(),但由于会话数据被锁定 为了防止并发写入,只有一个脚本可以在会话上运行 随时。将框架集与会话一起使用时,您将 体验由于这种锁定而一一加载的帧。你可以 通过结束会话来减少加载所有帧所需的时间 会话变量的所有更改完成后。

            在我的情况下,这只发生在使用Xdebug 进行调试时,当我多次触发同一个脚本并因此多个进程试图操纵同一个会话时。不知何故,会话无法再被解锁。

            【讨论】:

              猜你喜欢
              • 2015-10-02
              • 1970-01-01
              • 2016-07-26
              • 1970-01-01
              • 1970-01-01
              • 2012-11-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多