如何在PHP中重定向后解决丢失会话的问题?
最近,我遇到了一个在重定向后失去会话的常见问题。在搜索了这个网站之后,我仍然找不到解决方案(尽管this最接近)。
更新
我找到了答案,我想我会在这里发布,以帮助遇到同样问题的人。
答案 0 :(得分:178)
首先,执行这些常规检查:
session_start();
。因此,安全的赌注是将其放在页面的开头,在开始<?php
声明之后立即进行。还要确保在打开<?php
声明之前没有空格/制表符。header
重定向后,使用exit();
结束当前脚本(其他人也建议session_write_close();
和session_regenerate_id(true)
,您也可以尝试这些,但我会使用exit();
)register_globals
已关闭,您可以在php.ini
文件上以及使用phpinfo()
进行检查。有关如何将其关闭的信息,请参阅this。$_SESSION
超全局数组中的密钥不会被覆盖www.yourdomain.com
重定向到yourdomain.com
不会使会话向前发送。.php
(它会发生!)现在,这些是最常见的错误,但如果他们没有做到这一点,问题很可能与您的托管公司有关。如果一切都在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)
关键点
答案 13 :(得分:0)
这是我在此问题上的2美分,因为我没有看到任何人提及此案。
如果您的应用程序通过多个节点上的负载均衡器运行,则您无法将会话保存到文件中或需要为所有节点共享此路径,否则每个节点将拥有自己的会话文件,并且会遇到不一致的情况。
因此,我正在重构我的应用程序以使用数据库而不是文件系统。
答案 14 :(得分:0)
OP没有指定他是否重定向到同一页面(例如登录后),如果这样服务器/浏览器缓存也可能是问题
一种简单的解决方法是在URL末尾附加版本号(就像强制刷新.CSS文件时一样)
示例:
email
因此,将用户重定向到新页面一样对待
header('Location: index.php?v='.time());
答案 15 :(得分:0)
对我来说,快速有效的解决方案只是简单的双重重定向。我创建了2个文件:fb-go.php
和fb-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浏览器的行为。用户可以在其中看到类似的内容:
如果用户将选择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答案中没有提及的最常见原因:
磁盘空间问题。确保您的磁盘空间不满,需要一些空间来存储会话文件。
会话目录可能无法写入。您可以使用is_writable(session_save_path())
答案 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并销毁命令,第二次调用新的会话。