会话和php重定向不起作用

时间:2012-07-14 18:15:07

标签: php session redirect

我正在创建一个PHP脚本check.php来检查用户是否已登录。只有一个用户,因此密码直接写在php代码中。 check.php包含在每个相关网页的顶部(第1行),其中包含<? include "check.php"; ?>行。

代码

我删除了密码和域名。除此之外,以下是我的代码。 这里的要点是您在登录页面输入密码,然后通过POST将其发送到此脚本。

如果密码正确 xxx,会话login将存储true

如果密码不正确,但 设置,意味着用户键入错误,则任何现有会话都以session_destroy()结束,这意味着他已退出。

如果他到达某个页面但未登录,则会话login应为false或未设置,这意味着将使用} elseif(!($_SESSION['login'])) {

最后,如果他点击注销按钮,他会使用网址check.php?logout=true发送到此脚本。 logout=true应该在最后的elseif语句中的$_GET中捕获,并且会话应该在那里结束。

<?
ob_start();
session_start();


if($_POST['password'] == 'xxx') {   // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");

} elseif (isset($_POST['password'])) {  // Wrong password

    session_destroy();
    header("Location: http://www.url.com/administration/login.php?true");

} elseif(!($_SESSION['login'])) {   // Check at every page

    header("Location: http://www.url.com/administration/login.php");

} elseif($_GET['logout']) { // Log out

    session_destroy();
    header("Location: http://www.url.com/");

}
ob_flush();
?>

问题

在每个if语句中,我尝试重定向。我使用header("Location:...),但它在任何情况下都不起作用。由于header命令必须是根据规范发送到浏览器的第一个请求,因此我使用ob_start();ob_flush();作为described here。无论有没有这些都无效。

此外,会话存在无法存储内容的问题。由于某种原因,我无法将true存储在会话中。我的代码是否存在问题导致其失败?

作为测试,我尝试在每个echo / if语句中编写ifelse命令。从那时我发现脚本总是进入第三个语句 - 带有!($_SESSION['login'])的语句。

问题

到目前为止一切顺利。这告诉我脚本能够检测到会话未设置 剩下的两个问题是:

  • 为什么语句中的重定向不起作用,因为没有重定向,
  • 为什么无法首先设置会话。

任何建议都将受到赞赏。


更新1

为了清楚说明发生了什么(以及未发生的事情),我在不同的地点放了一些echo。以上代码的这段代码包含一些额外的echo s:

...
echo "Input: " . $_POST['password'];
echo "<br>Session before: " . $_SESSION['login'];

if($_POST['password'] == 'xxxx') {  // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");
    echo "<br>Session after: " . $_SESSION['login'];
    echo "<br>The first if works";

} ...

返回以下输出:

Input: xxxx
Session before:
Session after: 1
The first if works

(xxxx是密码;它是正确的。)

这是您登录的情况。您刚刚编写了密码并已发送到check.php

所以,我在这里可以看到它按原样访问第一个if。会话正确设置为true(或1)。当我刷新页面时,会话不再被设置。不应该吗?

header重定向显然没有做任何事情。


更新2

所以,感谢下面@EmilF的答案,我发现我的会话ID - 我可以用echo session_id();打印到屏幕 - 在每次页面转换或页面刷新时都会更改为一些新的随机数。我看起来好像存储在会话中的数据被遗忘了,因为新的会话ID指向其他地方。

使用:

<?
session_id('cutckilc16fm3h66k1amrrls96');
session_start();
...

其中cutckilc16fm3h66k1amrrls96只是一个随机数,会话ID是固定的,现在可以在页面刷新后再次检索存储的数据。这非常有效;虽然有点奇怪但是有必要。

现在我只需要标题重定向工作......

嗯,这闻起来像被关闭的东西。会话和标头功能已更改。也许这是来自主机的一些PHP设置。阻止标头请求的东西。

继续......

更新3 - 已解决

请参阅下面的答案。

当我将文件更改为另一种编码格式时,在文件的开头会创建一些奇怪的符号,例如:从ANSI到UTF-8。创建的符号是,我在自己的编辑器中看不到它们。因为它们位于php脚本的前面,所以它们会阻止headersession_start()正常工作。为什么他们被创造出来对我来说仍然是一个谜。

4 个答案:

答案 0 :(得分:3)

Okey,让我们列出你可以在这里调试的所有内容,并提及你已经做过的事情(所以其他人可以阅读):

  • 您是否安装了HTTP Header之类的内容?然后,您可以查看是否已将Location:标头发送到您的浏览器。
  • 我想你没有收到任何错误信息,对吗?您是否设置了error_reporting(E_ALL);
  • 尝试为var_dump()数组执行$_POST
  • 您还可以在浏览器中查看Cookie吗?我通常使用Firefox web-developer工具栏插件,它有一个菜单 Cookie - &gt;显示cookie信息。在那里你应该看到一个PHPSESSID cookie(登录后)。如果没有,您的网址应包含有关会话ID的一些信息(如下所示:?PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4)。否则,PHP无法找到会话,因为它不知道哪个会话属于您。

如果这无助于检查cookie是否已设置:

  • 再次打开标头插件,然后执行登录。检查服务器是否向您发送cookie。这必须在Set-Cookie命令中完成。它可能如下所示:Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/
  • 如果服务器未设置cookie,请检查php.ini中的设置。必须设置session.use_cookies = 1设置,必须设置为1On才能允许PHP使用Cookie。
  • 如果服务器确实设置了cookie,但您的浏览器不允许,请检查浏览器中的cookie选项。另请查看php.ini的{​​{1}}设置。如果设置为session.use_only_cookies = 0,则禁止PHP使用URL,如果浏览器不接受cookie。出于安全原因,这通常是被禁止的,因为人们将URL复制到朋友,然后这些朋友将接管已登录的会话;)因此,只需将其设置为1以进行调试。
  • 0 var_dump()的返回值。如果PHP无法正确启动会话,它将返回false。

答案 1 :(得分:2)

这里解开了谜团: Byte Order Mark

enter image description here

你会找到最佳答案:

https://stackoverflow.com/a/8028987/424004

答案 2 :(得分:1)

尝试使用session_id()打印PHPSESSID。如果你保持清爽,你会得到相同的输出吗?

如果没有尝试设置id:session_id('cutckilc16fm3h66k1amrrls96')

http://php.net/manual/en/function.session-id.php

现在应该可以使用,但所有用户使用相同的会话。

问题可能是这样的: PHP Session data not being saved

答案 3 :(得分:0)

经过许多漫长的日日夜夜的测试,阅读和询问以及参与者对这个问题的大量帮助 - 非常感谢您的努力! - 我慢慢地达到了这个相当神秘的解决方案问题。
我找到的解决方案,但我仍然没有解释......

因此,如更新2中所述,我从@EmilF的答案中发现会话ID不断变化。然后想到了一个服务器/主机问题。我联系了主持人 - one.com - 他最初和我一样不明白,为什么它不起作用。

然后他告诉我,check.php文件的开头有一些相当奇怪的符号。我在自己的编辑器中看不到它们。在我通过one.com提供基于浏览器的FileManager软件访问文件之前,它们不可见。

问题和解决方案

文件顶部如下所示:

<?
ob_start();
session_start();


if($_POST['password'] == 'xxx') {   // Correct password

    $_SESSION['login'] = true;
...

您可以在开头看到奇数符号。正如我所说,他们在我自己的编辑器Notepad ++中不是,也不在常规记事本中。我将文件发送给朋友检查,他在编辑Coda中看不到它们。

这些符号当然会作为浏览器的输出。因此,这是对session_start()header(Location:...之前发生的浏览器的请求。因为这两个命令必须优先于任何浏览器请求,所以在这种情况下它们现在不起作用。

会话和header命令现在可以完美删除符号。

仍然没有解释......

我不知道他们为什么会在那里,但经过更多测试我发现他们是如何到那里的:

在Notepad ++中,我可以在菜单中更改编码格式。当我从fx ANSI更改为UTF-8时,符号出现了。 在普通的记事本中,我可以在“另存为”窗口中将其保存为UTF-8选项。在这种情况下,符号也会出现。

在任何情况下,当我通过基于浏览器的编辑器查看代码时,我只能看到符号,该编辑器直接从服务器获取文件。并且编辑器始终是创建的。

我对此没有解释。对于另一个SO问题,这可能是一个很好的主题。

感谢所有试图帮助我的人。我在这里回答这个问题,因为这个的答案。但是所有的帮助和调试技巧都非常受欢迎并且非常有用。

非常感谢,祝大家夏天好。