PHP 输出缓冲:何时/是否用于不同类型的实际现有站点和应用程序


PHP output buffering: When/whether to use for different kinds of real existing sites and applications?

主要

在WordPress上下文中工作,我在我的PHP代码中基本上没有输出缓冲,但我最近开始尝试它,并尝试简单地作为用户识别在典型的(对我来说)场景中是否有任何明显的性能影响。不能说我在那里取得了任何决定性的成就,但我不知道我的实验是否真的适用于放大的情况。

的总体印象是,除非我有很好的理由使用它 - 可能涉及我目前通常不感兴趣的那种脚本 - 我应该避免它。然而,我会读到一些建议,我可以在一个或另一个正常上下文中使用缓冲(例如,呈现一大块HTML的短代码),我经常看到它被我钦佩并试图模仿的人在代码中使用。我已经看到熟悉的 ob_start() 等序列用于渲染甚至非常小的输出,这些输出没有进一步调整:例如菜单或其他短列表。

我还看到有人断言,除非在特殊情况下,否则在编写良好的代码中根本不需要输出缓冲。请参阅StackOverflow问答 这里 为什么在PHP中使用输出缓冲?,举一个例子。其他人会说它只有在需要对输出进行一些操作时才有用 - 比如内容preg_replace - 但你不需要输出缓冲区来做这种事情(任何 ol' 变量都可以)。

在我遇到的大多数现实世界实例中,某些版本的页面缓存也会被使用,有时还会使用几个不同的插件,每个插件都有自己的缓存。考虑到有多少函数本身将使用大量嵌套/辅助 HTML 生成函数,您可以轻松地在每页生成数千个小嵌套缓冲块: 假设 foreach 循环在较大的页面中生成 n 个博客评论: 每个博客评论都由一个函数呈现,可以单独缓冲。每个注释函数可以在输出注释线程的函数的 foreach 循环中调用,并且其输出也可以缓冲。然后,输出包含评论线程的帖子的函数可以在呈现之前进行输出缓冲。整个页面,包括各种独立的输出缓冲模板、插件、小部件、菜单等,也可以进行输出缓冲。

在什么时候,它中的任何一个是有用的,或者完全适得其反?

如果答案涉及"好吧,你不会在你的博客中注意到,但你需要它用于BuzzFeed或纽约时报"的任何元素,或者相反,我如何估计何时达到这一点?

在这一点上,我倾向于尽可能干净地编写代码,并让(我所理解的)内置的 PHP、浏览器、服务器等、缓冲和显式缓存函数完成使页面或其元素高效快速地加载的工作,这才是真正的目标,不是吗?

使用模板引擎时,代码通常只输出一次 — 在生成整个页面代码之后。因此,在这种情况下通常不需要输出缓冲。

输出

缓冲真正不可避免的唯一情况是捕获var_dump()phpinfo()等函数的输出,而不将其发送到浏览器。此外,这对于某些使用 echo 但不提供直接以字符串形式获取结果的功能的第三方库非常有用。

我将发布此作为我自己问题的答案,尽管不是假设没有更好的问题,因为我遇到了一种情况,甚至可能有资格成为某种类型的插件的常见情况,包括我实际上非常感兴趣的类型。答案主要适用于WordPress和使插件可扩展。

简而言之,为了提供一个过滤器 - 使用常见的WordPress"apply_filters"功能 - 你经常需要能够一次捕获整个HTML输出。当创建一个混合了HTML和辅助函数的大型复杂块时,使用ob_start()/ob_get_[]序列将是实现这一目标的更有效的方法。

所以:我目前正在处理的一个插件输出了一个表,该表的元素使用许多辅助函数组合在一起。现在,我可以想象做整个事情,向单个变量添加内容,但是在开始时启动输出缓冲,然后编写代码而无需额外的$html .= [more and more HTML and PHP]抽象层,这要容易得多,也更经济 最后,代码将整个输出分配给一个变量 - $html = ob_get_clean();,然后返回带有apply_filters函数的变量: return apply_filters( 'filter-tag' , $html ); 此外,ob_start() 和 ob_get_clean() 标记代码中有意义的点,以提供do_action钩子。