【问题标题】:echo after session会话后回显
【发布时间】:2011-06-02 17:53:08
【问题描述】:


我有以下代码:

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

?>

我在这里的第一次尝试是在session_start();之后echo "inputAction.php started";

但是,我发现我得到了一个错误:

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 会出错吗?
这是否意味着在session_start 之后不使用echo 是一个规则?
session_start之后我可以使用其他打印日志的方式(替代echo)吗?

【问题讨论】:

    标签: php html session


    【解决方案1】:

    如果您希望它回显然后重定向,以便用户可以看到它,您可以使用一些好的、老式的 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=,这意味着您要么测试两次,要么只是将 echo 放在 ifs 中。当然,如果使用 ob_start(),初始回显在哪里并不重要,因为它只会在脚本运行完成时输出。

    另外,你真的不应该在 Session 中存储密码。

    【讨论】:

      【解决方案2】:

      您已经使用\n\n 向浏览器发送了信息,因此浏览器构建了一个带有默认标题的页面,就像您发送任何文本(甚至是单个字符)一样。

      浏览器的想法是,“好吧,这只是纯文本,所以我会尽我所知将其转换为 HTML 并输出。”在此过程中,会生成标题并创建文档正文,因此在重新启动此过程(刷新)之前,您要发送的任何更多标题都将被忽略。

      为了避免这种情况发生,在您准备好开始构建页面之前,不要向浏览器发送任何信息。

      对象缓冲是一个中等难度的主题,如果您以前没有做过,需要一段时间才能正确完成。

      【讨论】:

      • 那么我该如何登录呢?我可以使用 echo 的任何替代方法吗?
      • 您可以添加一个会话变量,该变量会随着代码到达它而更新,然后在您准备好后回显它。假设有五个级别,然后你回显值“3”,你知道它只到了那个点。
      【解决方案3】:

      调用header() 函数会产生该警告。 header() 函数为您发回的响应设置 HTTP 标头。并且 HTTP 标头必须是响应中的第一件事。在它们之前不能显示其他输出。

      这个问题有很多解决方案。一种是打开output buffering,它会神奇地解决这个问题。更好的解决方案是构建您的代码,以便在调用header()(或session_start() 函数)之前不输出任何内容。如果你会使用一些 MVC 框架(cakephp、symphony、zend,...),你甚至不必担心它。

      这个问题已经在这里讨论过很多次了(这是关于 PHP 的最流行的问题之一)。看看这个search results

      还要花一些时间阅读 PHP 的错误消息。您提供的错误消息清楚地表明错误是在header() 行中“抛出”的,以及哪一行开始输出。

      【讨论】:

      • 那么有没有办法在不使用 header() 的情况下重定向页面? (所以我可以做回声的事情?)
      • 是的,打开输出缓冲。只需将Ob_Start(); 放在脚本的开头即可。
      【解决方案4】:

      不,规则是不要在header 之前输出任何内容。如果您仔细查看错误消息,它会显示:“无法修改第 16 行的标头信息 [...]”,因为“输出开始于 [...]:4”。

      输出开始的行不需要是第一个带有 echo 的行,因为 PHP 也有一个内部缓冲区,不会在每次 echo 调用时刷新。

      如果你想在header 之前输出一些东西,你需要使用output control 来缓冲它。因此,只需在其他任何操作之前调用ob_start,每个输出都会被缓冲,这样即使某些输出已经发生,也可以修改 HTTP 标头:

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

      【讨论】:

      • 那么有没有办法在不使用 header() 的情况下重定向页面? (所以我可以做回声的事情?)
      • 重定向不需要回显,因为重定向的页面(301页面)不应该有任何内容,而且用户毕竟看不到文字。
      • 无论如何,flush不会只是将文本输出到浏览器,导致创建标题,这让我们回到原来的问题吗?
      • @Jannis:带有重定向状态代码和 Location 字段的响应应该包含一个带有指向同一位置的链接的文档。
      • -1 表示错误的解决方案。如果发生重定向,明智的程序永远不会回显任何内容。
      【解决方案5】:

      因为您在 else 语句中使用了 header() 函数,所以只要您的代码进入那里,它就会尝试重定向您的页面。但是,正如 Gumbo 所说,如果在调用之前有任何输出到浏览器,header() 会抛出错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-21
        • 2014-10-21
        • 1970-01-01
        • 2017-08-09
        • 2018-07-04
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        相关资源
        最近更新 更多