重定向后PHP会话丢失

时间:2013-06-21 18:49:34

标签: php session redirect session-cookies shared-hosting

如何在PHP中重定向后解决丢失会话的问题?

最近,我遇到了一个在重定向后失去会话的常见问题。在搜索了这个网站之后,我仍然找不到解决方案(尽管this最接近)。

更新

我找到了答案,我想我会在这里发布,以帮助遇到同样问题的人。

34 个答案:

答案 0 :(得分:178)

首先,执行这些常规检查:

  1. 确保在调用任何会话之前调用session_start();。因此,安全的赌注是将其放在页面的开头,在开始<?php声明之后立即进行。还要确保在打开<?php声明之前没有空格/制表符。
  2. header重定向后,使用exit();结束当前脚本(其他人也建议session_write_close();session_regenerate_id(true),您也可以尝试这些,但我会使用exit();
  3. 确保在您用于测试的浏览器中启用了Cookie。
  4. 确保register_globals已关闭,您可以在php.ini文件上以及使用phpinfo()进行检查。有关如何将其关闭的信息,请参阅this
  5. 确保您没有删除或清空会话
  6. 确保$_SESSION超全局数组中的密钥不会被覆盖
  7. 确保您重定向到同一个域。因此,从www.yourdomain.com重定向到yourdomain.com不会使会话向前发送。
  8. 确保您的文件扩展名为.php(它会发生!)
  9. 现在,这些是最常见的错误,但如果他们没有做到这一点,问题很可能与您的托管公司有关。如果一切都在localhost上有效,但在远程/测试服务器上却没有,那么这很可能是罪魁祸首。因此,请检查您的托管服务提供商的知识库(也尝试他们的论坛等)。对于像FatCow和iPage这样的公司,他们要求您指定session_save_path。像这样:

    session_save_path('"your home directory path"/cgi-bin/tmp');
    session_start();
    

    (将“您的主目录路径”替换为您的实际主目录路径。这通常位于您的控制面板(或等效路径)中,但您也可以在根目录中创建test.php文件并键入:< / p>

    <?php echo $_SERVER['SCRIPT_FILENAME']; ?>
    

    'test.php'之前的位是您的主目录路径。当然,请确保该文件夹实际存在于根目录中。 (某些程序在同步时不会上传空文件夹)

答案 1 :(得分:22)

你应该在标题调用之后使用“exit”

header('Location: http://www.example.com/?blabla=blubb');
exit;

答案 2 :(得分:13)

我尝试了所有可能的解决方案,但没有一个适合我!当然,我正在使用共享托管服务。

最后,我通过使用“相对网址”解决了这个问题。在重定向标题内!

header("location: http://example.com/index.php")

使会话cookie无效

header("location: index.php")

像魅力一样工作!

答案 3 :(得分:5)

我遇到了同样的问题。我工作了几个小时,这让我很疯狂。

在我的情况下,由于Chrome和Firefox中的缺少favicon.ico ,问题是404。其他航海家工作得很好。

答案 4 :(得分:3)

这让我困扰了很长时间(这个帖子很棒!)但是对于那些仍然无法在页面重定向之间进行会话的人来说......我必须进入php.ini文件并且打开cookies:

session.use_cookies = 1 

我认为会议没有使用cookies ......实际上我知道他们应该......但这至少解决了我的问题,直到我能够理解大局可能会发生什么。

答案 5 :(得分:3)

虽然我的情况略有不同,但我遇到了类似的问题。 我在主机名为windows且IP地址为192.168.56.2的计算机上进行了本地开发设置。

我可以使用以下任一方式访问系统:

登录后,我的PHP代码将使用以下方式重定向:

header('http://windows/');

如果用于访问系统的先前域名不是windows,则会话数据将丢失。我通过将代码更改为:

来解决这个问题
header('http://'.$_SERVER['HTTP_HOST'].'/');

无论用户放入何种本地域名或IP地址,它现在都可以使用。

我希望这对某人有用。

答案 6 :(得分:3)

我在一个特定页面上遇到了这个问题。我正在重定向之前在其他页面中设置$ _SESSION值,一切正常。但是这个特定的页面没有用。

最后我意识到在这个特定的页面中,我在页面的开头摧毁了会话,但从未再次启动它。所以我的销毁功能改为:

function sessionKill(){

    session_destroy();

}

为:

function sessionKill(){

    session_destroy();
    session_start();

}

一切正常!

答案 7 :(得分:1)

另一个可能的原因:

这是我的服务器存储空间。我的服务器磁盘空间已满。所以,我在我的服务器中删除了一些文件和文件夹并尝试过。

它工作了!!!

我正在AWS Dynamo DB中保存会话,但它仍然希望我的服务器中有一些空间来处理会话。不知道为什么!!!

答案 8 :(得分:1)

如果您使用session_set_cookie_params(),可能需要检查是否将第四个参数$secure作为true传递。如果是,那么您需要使用https访问该网址。

$secure param为true表示会话仅在安全请求中可用。这可能会比在舞台或生产环境中更多地影响您本地。

提及它是因为我今天大部分时间都在努力寻找这个问题,这就是为我解决的问题。我刚刚加入这个项目,没有人提到它需要https。

因此,您可以在本地使用https,也可以将$secure参数设置为FALSE,然后在本地使用http。当您推进更改时,请确保将其设置为true。

根据您的本地服务器,您可能需要在服务器的DocumentRoot中修改httpd-ssl.conf,以便为您的本地网址提供https。

答案 9 :(得分:1)

我几天都在苦苦思索,检查/尝试所有解决方案,但我的问题是我在重定向后没有再次呼叫session_start();。我只是假设会议还活着#39;

所以别忘了!

答案 10 :(得分:1)

我遇到了同样的问题并找到了最简单的方法。 我只是重定向到一行重命名.html与1行JS

<!DOCTYPE html>
<html>
<script type="text/javascript">
<!--
window.location = "admin_index.php";
//–>
</script>
</html>

而不是PHP

header_remove();
header('Location: admin_login.php');
die;

我希望这会有所帮助。

爱 克

答案 11 :(得分:0)

对我来说,错误是我试图在会话中保存一个不可序的对象,以便在尝试编写会话时抛出异常。但由于我的所有错误处理代码已经停止了任何操作,我从未看到错误。

我可以在Apache错误日志中找到它。

答案 12 :(得分:0)

关键点

  1. 请勿在返回页面上启动会话。
  2. 不使用会话变量,也不包含header.php哪个用户会话变量
  3. 插入付款信息和状态后,只需链接到首页或个人资料页面

答案 13 :(得分:0)

这是我在此问题上的2美分,因为我没有看到任何人提及此案。

如果您的应用程序通过多个节点上的负载均衡器运行,则您无法将会话保存到文件中或需要为所有节点共享此路径,否则每个节点将拥有自己的会话文件,并且会遇到不一致的情况。

因此,我正在重构我的应用程序以使用数据库而不是文件系统。

答案 14 :(得分:0)

OP没有指定他是否重定向到同一页面(例如登录后),如果这样服务器/浏览器缓存也可能是问题

一种简单的解决方法是在URL末尾附加版本号(就像强制刷新.CSS文件时一样)

示例:

email

因此,将用户重定向到新页面一样对待

header('Location: index.php?v='.time());

答案 15 :(得分:0)

对我来说,快速有效的解决方案只是简单的双重重定向。我创建了2个文件:fb-go.phpfb-redirect.php

fb-go.php的位置如下:

session_start();

$_SESSION['FBRLH_state'] = 'some_unique_string_for_each_call';

header('Location: fb-redirect.php');

和fb-redirect:

session_start();

header('Location: FULL_facebook_url_with_' . $_SESSION['FBRLH_state'] . '_value');

还值得一提的是Android Chrome浏览器的行为。用户可以在其中看到类似的内容:

Android

如果用户将选择Facebook应用,则会话会丢失,因为它是在Facebook浏览器(而不是Chrome)中打开的,该浏览器正在存储用户会话数据。

答案 16 :(得分:0)

当我在header()函数中使用相对路径“ dir / file.php”对我有用。 我认为当您使用完整的URL重定向时,由于某种原因,会话没有被保存。

//Does retain the session info for some reason
header("Location: dir");

//Does not retain the session for some reason
header("Location: https://mywebz.com/dir")

答案 17 :(得分:0)

对我来说,这是权限错误,并且可以解决:

  

chown -R nginx:nginx / var / opt / remi / php73 / lib / php / session

我已经在PHP上测试了几个小时,最后一次测试是我创建了两个文件session1.php和session2.php。

session1.php:

session_start();

$_SESSION["user"] = 123;

header("Location: session2.php");

session2.php:

session_start();

print_r($_SESSION);

,它正在打印一个空数组。

在这一点上,我认为这可能是服务器问题,实际上是。

希望这对某人有帮助。

答案 18 :(得分:0)

ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
session_start();

来不及回复,但这对我有用

答案 19 :(得分:0)

今天我在一个项目中遇到了这个问题,我不得不将此参数更改为false(或删除这些行,默认情况下是禁用的):

ini_set( 'session.cookie_secure', 1 );

发生这种情况是因为实际项目通过http而不是仅通过https运行。在文档http://php.net/manual/en/session.security.ini.php

中找到了更多信息

答案 20 :(得分:0)

我通过向组授予对PHP存储会话文件的路径的写权限进行修复。您可以使用session_save_path()函数找到会话路径。

答案 21 :(得分:0)

经过几天的调试,我解决了这个问题,这完全是因为我来自PayPal Express Checkout的返回URL没有“ www”。 Chrome认识到应该对域进行相同的处理,但其他浏览器有时则不一样。使用会话/ cookie和绝对路径时,请不要忘记“ www”!

答案 22 :(得分:0)

现在GDPR是一个东西,访问这个问题的人可能会使用cookie脚本。那个脚本给我带来了问题。显然,PHP使用名为PHPSESSID的cookie来跟踪会话。如果该脚本删除它,则会丢失数据。

我使用了this cookie script。它可以选择启用“基本”cookie。我在列表中添加了PHPSESSID,脚本停止了删除cookie,所有内容都重新开始工作。

您可以启用某些PHP设置以避免使用PHPSESSID,但如果您的Cookie脚本是导致问题的原因,那么为什么不修复

答案 23 :(得分:0)

确保在session_write_close和您设置会话之间未调用session_start()

session_start();

[...]

session_write_close();

[...]

$_SESSION['name']='Bob'; //<-- won't save

答案 24 :(得分:0)

我遇到了同样的问题,我疯狂地在我的代码中搜索答案。最后,我发现我的托管最近在我的服务器上更新了PHP版本,并且没有在php.ini文件上正确设置php.ini参数。

因此,如果有人读到此内容,请先检查ID cl_id start_dt end_dt as_dt pc_id max_role max_pc_id first_as_DT 1 101 1/31/18 2/2/18 6/13/14 5245 red (null) 1 101 1/31/18 2/2/18 1/10/18 (null) red (null) 1 101 1/31/18 2/2/18 2/1/18 1457 red (null) 1 101 1/31/18 2/2/18 2/2/18 (null) red (null) config。

答案 25 :(得分:0)

首先,请确保在使用session_start()变量之前致电$_SESSION

如果您已停用错误报告,请尝试启用并查看结果。

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

@ dayuloli答案中没有提及的最常见原因:

  1. 磁盘空间问题。确保您的磁盘空间不满,需要一些空间来存储会话文件。

  2. 会话目录可能无法写入。您可以使用is_writable(session_save_path())

  3. 进行检查

答案 26 :(得分:0)

没有什么对我有用,但我找到了导致问题的原因(并解决了它):

检查您的浏览器Cookie并确保不同子域上没有 php会话Cookie (例如“ www.website.com ”的一个,以及“ <强> website.com “)。

这是由于错误地使用子域设置Cookie并在iframe中打开网页的JavaScript造成的。

答案 27 :(得分:0)

我也有同样的问题,重定向无法正常工作,并尝试了我能找到的所有解决方案,我的标题重定向正在表单中使用。

我通过将标题重定向放在不同的php页面中来解决它&#39; signin_action.php&#39;并通过我想要的url参数传递变量参数,然后在&#39; signin_action.php&#39;中重新分配它们。形式。

<强> signin.php

if($stmt->num_rows>0) {
$_SESSION['username'] = $_POST['username'];
echo '<script>window.location.href = "http://'.$root.'/includes/functions/signin_action.php?username='.$_SESSION['username'].'";</script>';
error_reporting(E_ALL);

<强> signin_action.php

<?php
require('../../config/init.php');
$_SESSION['username'] = $_GET['username'];
if ($_SESSION['username']) {

echo '<script>window.location.href = "http://'.$root.'/user/index.php";</script>';
exit();
} else {
echo 'Session not set';
}

?>

这不是一个漂亮的解决方案,但它起作用。

答案 28 :(得分:0)

如果您正在使用Wordpress,我必须添加此挂钩并在init上启动会话:

function register_my_session() {
    if (!session_id()) {
        session_start();
    }
}
add_action('init', 'register_my_session');

答案 29 :(得分:0)

在SO和其他博客上尝试了很多解决方案之后......对我有用的是将.htaccess添加到我的网站根目录。

RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursitename.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursitename\.com" [R=301,L]

答案 30 :(得分:0)

对我来说,Firefox已将会话ID(PHPSESSID)存储在Cookie中,但Google Chrome使用了GET或POST参数。 所以你只需要确保返回的脚本(对我来说:paypal checkout)在url或POST参数中提交PHPSESSID。

答案 31 :(得分:0)

只是为了记录...我有这个问题,经过几个小时的尝试后,问题是磁盘已满,并且php会话无法写入tmp目录...所以如果你有这个问题检查也是......

答案 32 :(得分:-2)

session_start();
error_reporting(E_ALL ^ (E_NOTICE | E_WARNING));
if(!isset($_SESSION['name_session'])){
    unset($_SESSION['name_session']);
    session_destroy();
    }   
if(isset($_SESSION['name_session'])){
    $username = $_SESSION['name_session'];
    }

答案 33 :(得分:-2)

首先通过破坏旧会话确保正确创建新会话。

session_start();
session_unset();   // remove all session variables  
session_destroy(); // destroy the session
session_start();

$_SESSION['username'] = 'username';

是的,session_start()被调用两次。一次调用unset并销毁命令,第二次调用新的会话。