输出缓冲区如何影响性能?

3
我正在编写一个 PHP 脚本,在我的 header() 函数之前的某个位置输出了文本,从而导致我的 header() 函数出现了如下所示的错误:

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

现在我的问题是,我想在 header() 函数之前和之后使用 ob_start()ob_flush()。但我曾经听说过输出缓冲区可能会对应用程序的性能产生负面影响,这是真的吗?
还是我只需坚持使用打印 JavaScript 函数重定向页面的想法。
感谢您抽出时间阅读。

1
非常感谢您们抽出时间并对我的问题做出积极贡献,现在我对事情的理解更透彻了,尤其是输出缓冲区让我有些困惑。在所有帖子的帮助下,我已能找到正确的方法。谢谢大家,你们节省了我很多思考时间。 - War Coder
4个回答

5

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

测试ob_start和相关函数,看看性能差异是否重要。如果是,寻找替代方法。

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

由于您可能正在执行类似以下内容的重定向:

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

在调用 header() 函数之前,您不应该打印任何内容,因为客户端不会对您打印的数据做出任何反应(除非我对HTTP有所遗漏)。

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


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

+1 指出数据直到调用 ob_flush() 才会被流式传输,这将导致较慢的加载时间(但不一定是较慢的生成时间)。 - strager
我有一个关于这个主题的问题,我可以在这里和你交流吗? - Shafizadeh

2

在输出后移动PHP代码可能会暴露出糟糕的应用程序设计。但我不知道你的具体情况,可以提出两种可能的解决方案。

  1. Split code into model (data processing) and view (output) (see MVC). This means that you are making decision about relocating even before displaying anything. I'd called this way preferred.
  2. If you really need to show output (or other headers sent), common way is combining JS and HTML (in 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框架,您还可以推荐哪些其他框架?我的意思是一个易于使用的框架。 - War Coder
实际上,大多数流行的框架都会强制你以某种形式使用MVC。此外,它们还会给你很多其他的好处,例如清晰的应用程序结构、ORM等。例如:http://cakephp.org/ 是不错的,但需要一些学习才能开始使用,http://codeigniter.com/ 看起来更容易入手。 - Sergey Galashyn
哦,我认为最重要的是:即使你现在花费一些时间将你现有的开发代码转移到框架中,你将在未来节省更多时间。 - Sergey Galashyn

0

回答你的最后一条评论:你可以使用 header('Location: '.$url) 在 PHP 中重定向页面,显然应该在任何其他输出之前进行,并建议在其后跟随 exit();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接