简体   繁体   English

会话后回显

[英]echo after session


I have the code below: 我有下面的代码:

<?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");
}

?>

My first attempt here is to echo "inputAction.php started"; 我的第一个尝试是echo "inputAction.php started"; after session_start(); session_start();

However, I found out that I got an error: 但是,我发现我遇到了一个错误:

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

But I notice that this will be fine if I comment out the echo after session_start(); 但是我注意到,如果我在session_start();之后注释掉回显,这会很好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");
}

?>

What happened? 发生了什么? Can somebody explain why echo makes the error? 有人可以解释为什么echo会导致错误吗?
Does that mean that it's a rule not to use echo after session_start ? 这是否意味着在session_start之后不使用echo是一个规则?
Any other ways to print logs (alternative to echo ) that I can use after session_start ? session_start之后可以使用其他任何方式打印日志(替代echo )吗?

No, the rule is rather not to output anything before header . 不,规则是不要在header之前输出任何内容。 And if you take a closer look onto the error message, it says: “Cannot modify header information […] on line 16” because “output started at […]:4”. 而且,如果您仔细查看错误消息,它会显示:“无法在第16行修改标题信息[…]”,因为“输出始于[…]:4”。

The line where the output started does not need to be the first one with echo as PHP does also have an internal buffer that is not flushed with every echo call. 输出开始的行不必是第一行带有echo因为PHP的内部缓冲区也不会随每次echo调用而刷新。

If you want to output something before header you need to buffer it using the output control . 如果要在header之前输出某些内容,则需要使用输出控件对其进行缓冲。 So just call ob_start before anything else and every output is buffered so that the HTTP header can be modified even if some output already happened: 因此,只需在其他任何内容之前调用ob_start ,每个输出都将被缓冲,以便即使某些输出已经发生,也可以修改HTTP标头:

<?php
ob_start();
session_start();
// …

You've already sent information to the browser with the \\n\\n , so the browser constructed a page with default headers, as it will do if you send it any text at all (even a single character). 您已经使用\\n\\n向浏览器发送了信息,因此浏览器构造了一个带有默认标题的页面,就像您向它发送任何文本(甚至是单个字符)一样。

The browser's thinking, "OK, this is just plaintext, so I'll make it into HTML the best I know how and output it." 浏览器的想法是:“好的,这只是纯文本,所以我将尽我所能将其制作成HTML并输出。” As it does this, headers are made, and the document body is created, so any more headers you want to send it are ignored until this process is restarted (with a refresh). 这样做时,将创建标题,并创建文档主体,因此将忽略要发送的任何其他标题,直到重新启动此过程(刷新)。

For this not to happen, don't send any information to the browser until you're ready for it to start constructing the page. 为避免这种情况发生,在准备好开始构造页面之前,请不要向浏览器发送任何信息。

Object buffering is an intermediate-difficulty topic that will take a while to get right if you haven't done it before. 对象缓冲是一个中等难度的话题,如果您之前没有做过,那将需要一段时间才能解决。

That warning is produced with calling the header() function. 该警告是通过调用header()函数产生的。 The header() function sets HTTP header for the response you are sending back. header()函数为您发送回的响应设置HTTP标头。 And HTTP header must be the first thing in the response. HTTP标头必须是响应中的第一件事。 No other output can be displayed before them. 在它们之前,无法显示其他任何输出。

There are many solutions to this problem. 有许多解决此问题的方法。 One is to turn on output buffering , which will magically take care of this. 一种是打开输出缓冲 ,这将神奇地解决这一问题。 The better solution is to structure your code so that you don't output anything before any calls to the header() (or session_start() function). 更好的解决方案是对代码进行结构化,以便在对header() (或session_start()函数)进行任何调用之前都不输出任何内容。 If you would use some MVC framework (cakephp, symphony, zend, ...) you wouldn't even have to worry about it. 如果您使用某些MVC框架(cakephp,symphony,zend等),您甚至不必担心。

This exact problem has been dealt here numerous times (it's one of the most popular questions about PHP). 这个确切的问题已经在这里解决了很多次(这是有关PHP的最受欢迎的问题之一)。 Look at this search results . 看一下这个搜索结果

Also invest some time in reading PHP's error messages. 还花一些时间阅读PHP的错误消息。 The error message you provided clearly states that the error was "thrown" in the header() line, and which line started the output. 您提供的错误消息清楚地指出,该错误已在header()行中“引发”,并且哪一行开始了输出。

Because you are using the header() function in your else statement, anytime your code goes in there, it tries to redirect your page. 因为您在else语句中使用header()函数,所以只要您的代码进入其中,它就会尝试重定向您的页面。 However, like Gumbo said, header() will throw an error if there is anything output to the browser before it is called. 但是,就像Gumbo所说的那样,如果在调用之前没有任何输出到浏览器,则header()将引发错误。

If you want it to echo that and then redirect, so that the user can see it, you could do it with some good, old-fashioned HTML, and you would have control over how long it took to move to the next page. 如果您希望它回显然后重定向,以便用户可以看到它,则可以使用一些不错的老式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.

But of course, you would still have to test the input to determine what url=, which means you'd either test twice or just put the echo in the ifs anyway. 但是,当然,您仍然必须测试输入以确定url =,这意味着您必须测试两次或将回声放入ifs中。 Of course, it doesn't matter where the initial echos are if using ob_start() because it will only be output when the script is finished running. 当然,如果使用ob_start(),则初始回声在哪里都没有关系,因为只有在脚本运行完成后才输出。

Also, you really shouldn't store passwords in the Session. 另外,您实际上不应该在会话中存储密码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM