我有以下代码:
<?php
session_start();
echo "\n\n";
echo "inputAction.php started";
//echo "<br/><br/>";
$name = $_POST["theUser"];
$passw = $_POST["thePassword"];
if (!strcmp($name, "myPassw") && !(strcmp($passw, "1234")) )
{
//echo "correct";
$_SESSION['sessionUser']=$name;
$_SESSION['sessionPassword']=$passw;
header("location:a.php");
}
else
{
//echo "wrong";
header("Location: index.php");
}
?>
我的第一次尝试是在echo "inputAction.php started";
session_start();
然而,我发现我收到了错误:
inputAction.php started
Warning: Cannot modify header information - headers already sent by (output started at /Library/WebServer/Documents/01032011/inputAction.php:4) in /Library/WebServer/Documents/01032011/inputAction.php on line 16
但是我注意到如果我在session_start();
<?php
session_start();
//echo "\n\n";
//echo "inputAction.php started";
//echo "<br/><br/>";
$name = $_POST["theUser"];
$passw = $_POST["thePassword"];
if (!strcmp($name, "myPassw") && !(strcmp($passw, "1234")) )
{
//echo "correct";
$_SESSION['sessionUser']=$name;
$_SESSION['sessionPassword']=$passw;
header("location:a.php");
}
else
{
//echo "wrong";
header("Location: index.php");
}
?>
发生什么事了?有人可以解释为什么echo
会出错吗?
这是否意味着echo
之后不使用session_start
的规则?
在echo
之后我可以使用的任何其他打印日志的方法(替代session_start
)?
答案 0 :(得分:3)
不,规则不是在header
之前输出任何内容。如果您仔细查看错误消息,它会说:“无法修改第16行的标题信息[...],因为”输出从[...]开始:4“。
输出开始的行不需要是echo
的第一行,因为PHP也有一个内部缓冲区,每次echo
调用都没有刷新。
如果要在header
之前输出内容,则需要使用output control缓冲它。因此,只需在其他任何内容之前调用ob_start
,并且每个输出都被缓冲,以便即使某些输出已经发生,也可以修改HTTP标头:
<?php
ob_start();
session_start();
// …
答案 1 :(得分:1)
您已经使用\n\n
向浏览器发送了信息,因此浏览器构建了一个包含默认标题的页面,如果您发送任何文本(甚至是单个字符),它将会执行此操作。< / p>
浏览器的想法是,“好吧,这只是明文,所以我会把它变成HTML,我知道怎么做并输出它。”在执行此操作时,将生成标头,并创建文档正文,因此在重新启动此过程(刷新)之前,将忽略您要发送它的任何标头。
为此,请不要向浏览器发送任何信息,直到您准备开始构建页面为止。
对象缓冲是一个中等难度的主题,如果你以前没有做过,需要一段时间才能做到正确。
答案 2 :(得分:1)
通过调用header()
函数生成警告。 header()
函数为您要发回的响应设置HTTP标头。 HTTP标头必须是响应中的第一件事。在它们之前不能显示其他输出。
这个问题有很多解决方案。一个是打开output buffering,这将神奇地照顾到这一点。更好的解决方案是构造代码,以便在调用header()
(或session_start()
函数)之前不输出任何内容。如果您使用一些MVC框架(cakephp,symphony,zend,......),您甚至不必担心它。
这个确切的问题已在这里多次处理(这是关于PHP的最流行的问题之一)。看看这个search results。
还花一些时间阅读PHP的错误消息。您提供的错误消息明确指出错误已在header()
行中“抛出”,并且哪一行开始输出。
答案 3 :(得分:0)
因为您在else语句中使用了header()函数,所以只要您的代码进入,它就会尝试重定向您的页面。但是,就像Gumbo所说的那样,如果在调用浏览器之前有任何输出,header()将抛出一个错误。
答案 4 :(得分:0)
如果你希望它回应然后重定向,以便用户可以看到它,你可以使用一些好的,老式的HTML来做,你可以控制移动到下一个所需的时间页。
session_start();
echo '<head><meta http-equiv="refresh" content="5;url=http://www.whatever.com/a.php"></head>';
echo "\n\n";
echo 'inputAction.php started';
etc.etc.etc.
但是当然,您仍然需要测试输入以确定url =,这意味着您要么测试两次,要么只是将回声放入ifs中。当然,如果使用ob_start(),初始回声的位置并不重要,因为它只会在脚本运行完毕后输出。
另外,你真的不应该在会话中存储密码。