我在互联网上阅读了相当多的资料,其中不同的作者建议使用输出缓冲。有趣的是,大多数作者仅仅因为它允许将响应头与实际内容混合而论证其使用。坦率地说,我认为负责任的Web应用程序不应该混合输出标题和内容,Web开发人员应该在其脚本中查找可能的逻辑缺陷,这会导致在生成输出后发送标头。这是我对ob_*
输出缓冲API的第一个参数。即使你得到的一点点便利 - 将标题与输出混合 - 使用它也不是一个足够的理由,除非你需要快速破解脚本,这通常不是严肃的Web应用程序中的目标或方式。
另外,我认为大多数处理输出缓冲API的人都没有考虑这样一个事实,即使没有启用显式输出缓冲,PHP与插入的网络服务器相结合,仍然会做一些内部无论如何缓冲。很容易检查 - 做一些短串的回声,睡10秒,然后做另一个回声。使用浏览器请求您的脚本,并观察空白页暂停10秒,此后两行都出现。在有人说它是渲染假象而不是流量之前,跟踪客户端和服务器之间的实际流量会显示服务器已生成Content-Length
标头,并为整个输出生成适当的值 - 表明输出是不是每次echo
调用都会逐步发送,而是在某个缓冲区中累积,然后在脚本终止时发送。这是我对显式输出缓冲的抱怨之一 - 为什么我们需要两个不同的输出缓冲区实现?可能是因为内部(不可访问的)PHP / Web服务器输出缓冲受PHP开发人员无法控制的条件限制,因此不可用?
在任何情况下,我为一,开始认为应该避免显式输出缓冲(一系列ob_*
函数)并依赖于隐式的,并使用良好的flush
函数来协助它,必要时。也许如果Web服务器有一些保证在每次回显/打印调用时实际向客户端发送输出,那么设置显式缓冲会很有用 - 毕竟不希望向客户端发送大约100的响应字节块。但是有两个缓冲区的替代方案似乎是一个有点无用的抽象层。
那么,最终,严肃的Web应用程序是否需要输出缓冲?
答案 0 :(得分:12)
严重的Web应用程序在某种特定情况下需要输出缓冲:
您的应用程序希望控制某些第三方输出的内容 代码,但没有API来控制代码发出的内容。
在这种情况下,您可以在处理之前致电
ob_start()
控制该代码,弄乱所写的内容(理想情况下是 回调,或者如果你必须检查缓冲区内容),和 然后调用ob_flush()
。
最终,PHP的ob_ 函数是一种机制,用于捕获一些其他位代码进入缓冲区你可以做什么搞乱。
如果您不需要检查或修改写入缓冲区的内容,则使用ob_start()
无法获得。
很可能,您的“严肃申请”实际上是某种框架。
为了使用输出缓冲,您不需要ob_start()
。您的网络服务器已经 缓冲您的输出。
使用ob_start()
不会让你更好的输出缓冲 - 它实际上可以通过“囤积”数据来增加应用程序的内存使用和延迟,否则这些数据将被发送到Web服务器客户已经。
ob_start()
... 在某些情况下,您可能需要根据应用程序最了解的某些条件,在 Web服务器刷新其缓冲区时控制。大多数情况下,您知道您刚刚编写了一个客户端可以使用的逻辑“单元”,并且您告诉Web服务器现在刷新 而不是等待输出填充缓冲区。要做到这一点,只需要正常发出输出,并用flush()
标记它。
更少见的是,在您有足够的数据发送之前,您需要保留来自Web服务器的数据。没有必要用一半的新闻来打断客户,特别是如果剩下的新闻需要一些时间才能获得。后来由ob_start
得出的简单ob_end_flush()
可能确实是最简单和最合适的事情。
如果您的应用程序负责计算只能在完整响应可用后确定的标题,那么可能可以接受。
但是,即使在这里,如果你做的不是通过检查完整的输出缓冲区来获得头文件,那么你也可以让web-server这样做(如果可以的话)。 Web服务器的代码经过编写,测试和编译 - 您不太可能改进它。
例如,如果应用程序在计算响应主体之前知道响应主体的长度,那么设置Content-Length
标头只会很有用。
你不应该ob_start()
来避免以下原则:
如果你这样做,他们会造成技术债务,这会让你有一天哭。
答案 1 :(得分:9)
好的,这是真正的原因:输出一切都没有开始。 想象一个应用程序打开SQL连接,并在开始输出之前不关闭它。会发生什么是您的脚本获得连接,开始输出,等待客户端获得它所需要的所有内容,最后,关闭连接。 Woot,2s连接,0.3s就足够了。
现在,如果您缓冲,您的脚本将连接,将所有内容放入缓冲区,最后自动断开连接,然后开始将生成的内容发送到客户端。
答案 2 :(得分:5)
如果您想将报告输出到屏幕但也通过电子邮件发送,输出缓冲使您无需重复处理以输出报告两次。
答案 3 :(得分:5)
最明显的用例是:
ob_gzhandler
或您可以自行设计的任意数量的过滤器); 我使用的API只支持输出(而不是返回值),我想用phpQuery 等库进行后续解析。答案 4 :(得分:3)
我出于某种原因使用输出缓冲...它允许我在开始处理请求后发送“位置”标题。
答案 5 :(得分:3)
输出缓冲在IIS上至关重要,它本身没有内部缓冲。关闭输出缓冲后,PHP脚本的运行速度似乎比在Apache上慢很多。打开它,它们的运行速度要快很多倍。
答案 6 :(得分:3)
这是一个古老的问题,但是没有人说过outbut buffering的一个重要特征是过滤。可以在将缓冲区发送到客户端之前对其进行预处理。
这是一个非常强大的概念,并开启了许多有趣的可能性。在一个项目中,我同时使用了两个过滤器:
启用输出过滤调用ob_start("callback")
,其中callback
是过滤功能的名称。有关更多详细信息,请参阅ob_start
的PHP手册:http://php.net/manual/en/function.ob-start.php
答案 7 :(得分:2)
我使用输出缓冲以避免通过字符串连接生成HTML,当我需要知道渲染操作的结果以在使用渲染之前创建一些输出。
答案 8 :(得分:1)
我们过去常常使用它来填充数据库中填充数据的长表的页面。你每隔x行刷一次缓冲区,这样用户就知道页面实际上正在工作。然后有人听说了可用性和页面,如有分页和搜索。
答案 9 :(得分:0)
如果您尝试在需要一些时间处理的页面中显示进度条,这将非常有用。由于PHP代码不是多线程的,因此如果处理挂起执行1个函数,则无法执行此操作。
答案 10 :(得分:0)
如果您正在进行大量数据库事务和处理,请使用输出缓冲来缓存文件中的数据,以用于其他类似的请求。