【问题标题】:How can an output buffer worsen performance输出缓冲器如何降低性能
【发布时间】:2009-02-08 20:53:51
【问题描述】:

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

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

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

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

感谢您的宝贵时间。

【问题讨论】:

  • 非常感谢大家的时间和对我的问题的积极贡献。现在我对事情有了更好的理解,尤其是让我困惑了一段时间的输出缓冲区。在所有帖子之后,我已经能够采用正确的方法。谢谢大家,你们都为我节省了很多思考。

标签: php output-buffering


【解决方案1】:

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

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

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

因为您可能会使用以下内容执行重定向:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • +1 指出在调用 ob_flush() 之前数据不会流式传输,这将导致加载时间变慢(但生成时间不一定会变慢)。
    • 我有一个关于这个话题的问题,请问here 有什么问题吗?
    【解决方案3】:

    输出后在 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;
      }
      

    附:这段代码是一个 Fusebox 框架。

    【讨论】:

    • 感谢您的建议。应该从项目一开始就应用 MVC 技术。除了 zend 框架,你还能推荐哪些其他框架?我的意思是一个易于使用的。
    • 实际上,大多数流行的框架都会强迫你以某种形式使用 MVC。他们还会给你很多其他的奖金,例如干净的应用程序结构,ORM 等。示例:cakephp.org 很好,但需要一些学习才能开始使用,codeigniter.com 似乎更容易上手。
    • 哦,最重要的是 imo:即使您现在花一些时间将现有的开发代码转移到框架中 - 您将来也会将其保存回来。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-15
      • 2020-06-02
      • 1970-01-01
      • 1970-01-01
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      相关资源
      最近更新 更多