重定向后PHP会话丢失

问题描述 投票:115回答:31

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

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

更新

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

php session redirect session-cookies shared-hosting
31个回答
182
投票

首先,执行以下常规检查:

  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(它发生!)

现在,这些是最常见的错误,但如果他们没有做到这一点,问题很可能与您的托管公司有关。如果一切都在localhost上运行,但在你的远程/测试服务器上没有,那么这很可能是罪魁祸首。因此,请检查您的托管服务提供商的知识库(也尝试他们的论坛等)。对于FatCow和iPage等公司,他们要求您指定session_save_path。像这样:

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

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

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

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


1
投票

我已经苦苦挣扎了几天,检查/尝试所有的解决方案,但我的问题是我没有在重定向后再次调用session_start();。我只是假设会议“还活着”。

所以不要忘记!


1
投票

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

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

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

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

根据您的本地服务器,您可能必须在服务器的DocumentRoot中编辑httpd-ssl.conf,以便为您的本地URL提供https。


1
投票

另一个可能原因:

那是我的服务器存储空间。我的服务器磁盘空间已满。所以,我已经删除了我的服务器中的几个文件和文件夹并尝试过。

它工作了!!!

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


0
投票

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

我通过将标题重定向放在不同的php页面'signin_action.php'并通过我想要的url参数传递变量参数然后在'signin_action.php'表单中重新分配它来解决它。

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';
}

?>

这不是一个美丽的解决方案,但它有效。


0
投票

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

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


0
投票

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


0
投票

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


0
投票

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

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

0
投票

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

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

0
投票

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

检查您的浏览器cookie并确保不同子域上没有php会话cookie(例如“www.website.com”和“website.com”)。

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


22
投票

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

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

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())查看

0
投票

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

所以,如果有人读到这个,请先检查php.ini配置。


0
投票

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

session_start();

[...]

session_write_close();

[...]

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

0
投票

如果您使用的是Laravel并且遇到此问题,那么您需要在重定向之前保存会话数据。

session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;

0
投票

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

我用过this cookie script。它可以选择启用“基本”cookie。我将PHPSESSID添加到列表中,脚本停止删除cookie,一切都开始重新运行了。

您可以启用一些PHP设置以避免使用PHPSESSID,但如果您的cookie脚本是问题的原因,为什么不解决这个问题。


0
投票

我经过多天的调试后修复了这个问题,这完全是因为来自PayPal Express Checkout的返回网址没有“www”。 Chrome认识到域名应该被视为相同,但其他浏览器有时没有。使用会话/ cookie和绝对路径时,不要忘记'www'!


0
投票

我修复了给PHP存储会话文件的路径的组写权限。您可以使用session_save_path()函数找到会话路径。


0
投票

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

ini_set( 'session.cookie_secure', 1 );

发生这种情况是因为实际项目仅通过http而不是https工作。在docs http://php.net/manual/en/session.security.ini.php中找到更多信息


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

回复太迟但这对我有用


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);

它正在打印一个空数组。

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

希望这有助于某人。


13
投票

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

最后,我通过在重定向头中使用'relative url'解决了这个问题!

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

使会话cookie无效

header("location: index.php")

像魅力一样工作!


-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'];
    }

5
投票

我有同样的问题。我工作了几个小时,它让我发疯了。

在我的情况下,问题是由于在Chrome和Firefox中仅缺少favicon.ico而被称为404。其他导航员工作得很好。


3
投票

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

session.use_cookies = 1 

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


3
投票

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

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

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

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

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

header('http://'.$_SERVER['HTTP_HOST'].'/');

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

我希望这可能对某人有用。


3
投票

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

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

function sessionKill(){

    session_destroy();

}

至:

function sessionKill(){

    session_destroy();
    session_start();

}

一切正常!


3
投票

我遇到了同样的问题。突然间,我的一些会话变量不会持久到下一页。问题结果是(在php7.1中)你的标题位置必须没有WWW,ex https://mysite。没关系,https://www.mysite。会失去那些会话变量。不是全部,只是那个页面。


1
投票

我有同样的问题,发现最简单的方法。我只是用1行JS重定向到重定向.html

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

而不是PHP

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

我希望这有帮助。

爱克

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