我正在制作一个 PHP 脚本check.php
来检查用户是否登录。只有一个用户,所以密码直接写在 php 代码中。包含在每个相关页面的check.php
顶部(第 1 行),并带有<? include "check.php"; ?>
。
编码
我已经删除了密码和域名。除此之外,以下是我的代码。这里的重点是您在登录页面输入密码,然后通过 POST 将其发送到此脚本。
如果密码是正确的 xxx,会话login
将存储true
.
如果密码不正确,但已设置,意味着用户输入了错误的内容,则任何现有会话都以 结束session_destroy()
,这意味着他已注销。
如果他到达一个页面但没有登录,则会话login
应该为 false 或未设置,这意味着} elseif(!($_SESSION['login'])) {
将使用 。
最后,如果他单击注销按钮,他将使用 url: 发送到此脚本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();
and ob_flush();
,如此处所述。无论有没有这些,它都不起作用。
会话也存在不存储内容的问题。由于某种原因,我无法true
在会话中存储。我的代码是否有问题导致它失败?
作为测试,我尝试echo
在每个if
/ifelse
语句中编写一个命令。从那我发现脚本总是进入第三个语句 - 带有!($_SESSION['login'])
.
问题
到现在为止还挺好。这告诉我脚本能够检测到会话未设置。
剩下的两个问题是:
- 为什么语句中的重定向不起作用,因为没有发生重定向,并且
- 为什么不能首先设置会话。
任何建议将被认真考虑。
更新 1
为了清楚地说明会发生什么(以及什么不会发生),我echo
在不同的位置添加了一些 s。上面的代码片段带有一些额外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();
...
wherecutckilc16fm3h66k1amrrls96
只是一个随机数,会话 id 是固定的,现在可以在页面刷新后再次检索存储的数据。这工作得很好;虽然仍然有点奇怪,但这是必要的。
现在我只需要标头重定向即可工作...
嗯,这闻起来像是被关闭的东西。会话和标头功能已更改。也许这是主机的一些 PHP 设置。阻止标头请求的东西。
待续...
更新 3 - 已解决
请看下面我的回答。
当我将文件更改为另一种编码格式时,文件开头会创建一些奇怪的符号,例如从 ANSI 到 UTF-8。创建的符号是
,我在自己的编辑器中看不到它们。因为它们在 php 脚本前面,所以它们阻止了header
andsession_start()
正常工作。为什么它们被创造出来对我来说仍然是一个谜。