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

时间:2016-04-24 17:08:25

标签: php wordpress output-buffering

主要在WordPress上下文中工作,我的PHP代码中大部分都没有输出缓冲,但我最近开始尝试使用它并尝试简单地将其视为典型的性能影响(对我而言) )场景。不能说我在那里取得了明确的成就,但我不知道我的实验真的适用于扩大规模的情况。

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

我也看到人们断言,除了特殊情况外,在编写良好的代码中根本不需要输出缓冲。请参阅StackOverflow Q& A在这里Why use output buffering in PHP?,举个例子。其他人会说,只有在需要对输出进行一些操作时才有用 - 比如内容的preg_replace - 但是你不需要输出缓冲来做那种事情(任何变量都会做)。

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

它会在什么时候有用,或者完全适得其反?

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

此时,我倾向于尽可能干净地编写代码,并让(我所理解的)内置PHP,浏览器,服务器等,缓冲和显式缓存功能使页面或其元素有效且快速地加载的工作,这是真正的目标,不是吗?

2 个答案:

答案 0 :(得分:1)

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

输出缓冲真正不可避免的唯一情况是捕获phpinfo()echo等函数的输出而不将其发送到浏览器。此外,这对于某些使用public static String readFile(String path, Charset encoding) throws IOException { byte[] encoded = Files.readAllBytes(Paths.get(path)); return new String(encoded, encoding); } public void jsouptest() throws IOException { // there is a file named "sample.html" in the project directory String htmlContent = readFile("sample.html", StandardCharsets.UTF_8); Document doc = Jsoup.parseBodyFragment(htmlContent, ""); Element body = doc.body(); String entryMetaText = body.select("div.entry-meta").get(0).text(); String imgLink = body.select("img.avatar").get(0).attr("src"); int commentPos = -1; if(entryMetaText.contains("AM")){ commentPos = entryMetaText.indexOf("AM") + 2; } else if(entryMetaText.contains("PM")){ commentPos = entryMetaText.indexOf("PM") + 2; } if(commentPos != -1) { entryMetaText = entryMetaText.substring(0, commentPos); } System.out.println(entryMetaText); System.out.println(imgLink); } 但未提供将结果直接作为字符串获取的第三方库非常有用。

答案 1 :(得分:0)

我发布这个作为我自己问题的答案,虽然不是假设没有更好的问题,因为我遇到的情况甚至可能属于某种类型的插件的常见问题-in,包括我实际上非常感兴趣的类型。答案主要适用于WordPress并使插件可扩展。

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

所以:我目前正在使用的插件输出一个表,其中的元素使用许多辅助函数放在一起。现在,我可以想象将整个内容添加到单个变量中,但是在开始时启动输出缓冲更容易,更经济,然后在没有{{1的额外抽象层的情况下编写代码最后,代码将整个输出分配给变量 - $html .= [more and more HTML and PHP],然后使用apply_filters函数返回变量:$html = ob_get_clean();此外,ob_start()和ob_get_clean()标记代码中的点提供do_action挂钩是有意义的。