PHP:在标题重定向之前,会话未保存

问题描述 投票:11回答:10

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

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

然后在session_start()之后的index.php的顶部,我有var_dumped $ _SESSION全局,而userID不在那里。正如我所说,我看了PHP手册(http://php.net/manual/en/function.session-write-close.php),session_write_closesession_regenerate_id(true)都没有为我工作。有人知道解决方案吗?

编辑:我的文件顶部有session_start()。当我在头重定向之前var_dump会话全局时,我在那里看到userID,但是在另一个文件中没有,这是在这个脚本的子目录中

php session header sessionid
10个回答
14
投票

我知道这是一个古老的缺点,但我找到了解决方案(对我而言)。我在标题后面放了一个出口。

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

这适合我


0
投票

使用exit强制终止脚本的另一个选择是使用session_write_close强制将更改写入会话存储。

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

As the documentation about session_write_close states:

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

会话数据通常在脚本终止后存储而不需要调用session_write_close(),但是由于会话数据被锁定以防止并发写入,因此任何时候只有一个脚本可以在会话上运行。将框架集与会话一起使用时,由于此锁定,您将体验到逐个加载的框架。只要对会话变量进行了所有更改,就可以通过结束会话来减少加载所有帧所需的时间。

在我的情况下,这只发生在Xdebug调试期间,当我多次触发相同的脚本,因此多个进程试图操纵同一个会话。不知何故,会话可能不再被解锁。


4
投票

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

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


1
投票

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

PHP代码, 在session_start(); $ _SESSION ['userID'] = $ user-> id; header('Location:/subdirectory/index.php');


0
投票

你有session_start();在顶端?

没有测试,但你不能做这样的事情:

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

我之前从未遇到过这个问题,很有趣


0
投票

userID没有任何关键字状态。

唯一的原因是$ _SESSION ['userID']被覆盖或删除。

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

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


0
投票

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


0
投票

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

有了会话,你必须做一些事情,并设置一些设置:

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

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

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

当我回到会议时,我也想知道这是如何结束的。


0
投票

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

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

然后,我在标题('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();

希望它能解决你的问题。


0
投票

这很烦人,但我终于想出了一个解决方案。

config.php我有:include'session.php';

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

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

问题解决了!

© www.soinside.com 2019 - 2024. All rights reserved.