3

我正在编写一个 php 脚本,在我的header()函数之前的某个地方,我已经将文本打印到浏览器,从而导致我的header()函数给了我一个众所周知的错误:

警告:无法修改标头信息 - 标头已发送。

ob_start()现在我的问题是,我有使用函数ob_flush()前后的意图。header()但是我曾经听说过输出缓冲区之类的东西会对应用程序的性能产生负面影响。这有多真实?

或者我应该坚持打印 Javascript 函数来重定向页面的想法。

谢谢你的时间。

4

4 回答 4

5

我们应该忘记小的效率,比如大约 97% 的时间:过早优化是万恶之源。

测试ob_start和朋友看看性能差异是否重要。如果是这样,请寻找替代方案。

header()最简单的选择是在打印之前移动呼叫。

因为您可能正在执行重定向,例如:

header('Location: /new/location/');

您不应该在此header()调用之前打印任何内容,因为无论如何客户端都不会对您打印的数据做任何事情(除非我缺少关于 HTTP 的内容)。

(Javascript 不是重定向的好选择,也不是meta刷新,除非您出于某种原因想要检测 Javascript。)

于 2009-02-08T20:56:52.433 回答
4

使用输出缓冲区需要服务器将 PHP 的整个输出存储在 RAM 中,因此如果它是一个大页面,您将最终使用相当多的内存 - 而且服务器还必须等到整个页面都完成在发送之前生成,这可能会导致小的延迟。但除此之外,我认为使用输出缓冲区并没有太大的劣势。对于您想要做的事情,这当然是一个合理的解决方案。

于 2009-02-08T20:57:40.417 回答
2

输出后在 PHP 代码中重新定位可以说明糟糕的应用程序设计。但我不知道你的情况,可以提出两种可能的方法。

  1. 将代码拆分为模型(数据处理)和视图(输出)(参见MVC)。这意味着您甚至在显示任何内容之前就已经决定重新定位。我认为这种方式是首选。
  2. 如果您确实需要显示输出(或发送的其他标头),常见的方法是结合 JS 和 HTML(在 noscript 中):

    if (headers_sent()) {
        print('<script type="text/javascript">( document.location.replace ) ? document.location.replace("'.$location.'") : document.location.href = "'.$location.'";</script>'."\n".'<noscript><meta http-equiv="Refresh" content="0;URL='.$location.'" /></noscript>');
    } else {
        header('Location: '.$location);
        exit;
    }
    

PS 这段代码是一段 Fusebox 框架。

于 2009-02-08T21:19:47.027 回答
0

只是回答你的最后一句话:你可以在 php 中使用它重定向页面,header('Location: '.$url)显然它应该在任何其他输出之前出现,建议紧随其后exit();

于 2009-02-08T20:59:20.727 回答