为什么在PHP中使用输出缓冲?
我在互联网上阅读了很多资料,其中不同的作者建议使用输出缓冲。 有趣的是,大多数作者认为它的使用只是因为它允许将响应头与实际内容混合在一起。 坦率地说,我认为负责任的Web应用程序不应混合输出标题和内容,Web开发人员应该在其脚本中寻找可能的逻辑缺陷,从而在输出生成后发送标题。 这是我对ob_*
输出缓冲API的第一个参数。 即使为了获得这么少的便利 - 混合标题和输出 - 这不是一个足够好的理由来使用它,除非需要快速修改脚本,这通常不是一个严肃的Web应用程序的目标或方式。
另外,我认为大多数处理输出缓冲API的人不会考虑这样一个事实:即使没有启用显式输出缓冲,PHP与插入的Web服务器结合, 仍然会进行一些内部缓冲 。 很容易检查 - 做一些短串的回声,睡10秒钟,并做另一个回声。 用浏览器请求您的脚本,并观看空白页暂停10秒,其后两行都会出现。 在一些人说它是渲染假象而不是流量之前,跟踪客户端和服务器之间的实际流量表明服务器已经为整个输出生成了一个适当值的Content-Length
头部 - 这表明输出没有发送每个echo
调用逐渐累积,但累积在某个缓冲区中,然后通过脚本终止发送。 这是我对显式输出缓冲的一个抱怨 - 为什么我们需要两个不同的输出缓冲区实现在另一个之上? 可能是因为内部(不可访问的)PHP / Web服务器输出缓冲受PHP开发人员无法控制的条件影响,因此不是真的可用?
在任何情况下,我都认为应该避免显式的输出缓冲(一系列ob_*
函数)并依赖隐式函数,并在必要时用良好的flush
函数来协助它。 也许,如果Web服务器有一定的保证能够通过每个echo / print调用将输出实际发送到客户端,那么设置显式缓冲会很有帮助 - 毕竟一个人不想用大约100个响应发送给客户端字节块。 但有两个缓冲区的替代方案看起来像是一个有点无用的抽象层。
那么,最终,严肃的Web应用程序需要输出缓冲吗?
是
严重的Web应用程序需要在特定情况下输出缓冲:
您的应用程序想要控制某些第三方代码输出的内容,但是没有API来控制该代码发出的内容。
在这种情况下,可以在将控制权交给该代码之前调用ob_start()
), ob_flush()
所写的内容(理想情况下使用回调函数,或者在必要时检查缓冲区内容),然后调用ob_flush()
。
最终,PHP的ob_functions是一种机制,用于捕获其他一些代码在可以混淆的缓冲区中执行的操作 。
如果您不需要检查或修改写入缓冲区的内容,则使用ob_start()
将不会获得任何结果。
很可能,您的“严肃申请”实际上是某种框架。
无论如何,你已经有了输出缓冲
你不需要ob_start()
来使用输出缓冲。 你的网络服务器已经做了缓冲你的输出。
使用ob_start()
并不能让你更好地输出缓冲 - 它实际上可能会通过“囤积”数据来增加应用程序的内存使用率和延迟,而这些数据本来会发送给客户端。
也许ob_start()
...
...为了方便冲洗
在某些情况下,您可能需要控制Web服务器刷新其缓冲区的时间,这取决于您的应用程序最了解的某些标准。 大多数情况下,你知道你刚写完一个客户端可以使用的逻辑“单元”,并且你正在告诉网络服务器立即刷新,而不是等待输出缓冲区填满。 要做到这一点,只需简单地发出你的输出,并用flush()
对其进行标记。
更少见的情况是,除非有足够的数据才能发送,否则您会希望从网络服务器中扣除数据。 没有一点中断客户的一半新闻,特别是如果其他新闻需要一些时间才能获得。 ob_end_flush()
稍后得出的一个简单的ob_start
可能确实是最简单和适当的事情。
...如果你对某些标题负责
如果您的应用程序负责计算只能在完整响应可用后才能确定的标头,则可以接受。
但是,即使在这里,如果通过检查完整的输出缓冲区来获得头部信息,你也不能做得更好,但是也可以让Web服务器去做(如果会的话)。 网络服务器的代码被编写,测试和编译 - 你不可能改进它。
例如,如果您的应用程序在计算响应主体之前知道响应主体的长度,那么只需设置Content-Length
标头即可。
不好的做法没有灵丹妙药
你不应该ob_start()
来避免以下规则:
如果你这样做,他们会造成技术债务,这会让你有一天哭泣。
好吧,这是真正的原因:输出在所有事情完成之前不会启动。 想象一下,在启动输出之前打开一个SQL连接并且不关闭它的应用程序。 发生什么事是你的脚本获得连接,开始输出,等待客户端获得所需的所有内容,最后关闭连接。 Woot,2s连接,0.3s就足够了。
现在,如果你缓冲,你的脚本连接,把所有内容放入缓冲区,最后自动断开连接,然后开始将生成的内容发送到客户端。
如果您想要将报告输出到屏幕并通过电子邮件发送,则输出缓冲功能可让您不必重复处理以输出报告两次。
链接地址: http://www.djcxy.com/p/34685.html上一篇: Why use output buffering in PHP?
下一篇: "headers already sent" error depending on output length?