开启WordPress博客的调试模式,网页底部有两条错误提示,类似:PHP Notice: ob_end_flush(): failed to send buffer of zlib output compression (1) in \wp-includes\functions.php on line 5373。
看到有错误提示实在是烦,而且这个存在很久了,今天狠起来直接升级到 PHP8.2版,居然没提示了,其实是因为php默认关闭了 zlib.output_compression
,但我还是希望两个同时开起来,不要打架。
在优化 PHP 输出时,开启 zlib 压缩(zlib.output_compression)和使用输出缓冲(Output Buffering)是两种常见的策略。其他语言如Java、Python等也有类似的输出压缩和缓冲刷新机制。
这两种方法主要用于优化PHP的性能输出,各有优劣,适用于不同的场景。本文将探讨下它们的特点、优势和劣势,并提供一些建议。
1、zlib.output_compression
zlib.output_compression 是PHP中用于压缩输出的配置选项,用于启用Gzip压缩输出。当开启时,PHP会自动压缩输出,而不需要额外的代码。这可以减少传输内容的体积,提高加载速度。在WordPress中,通常可以在 php.ini 文件中或者通过 .htaccess 文件来配置。
优势:
- 减少网络流量: 通过压缩输出,zlib.output_compression 可以显著减小传输给客户端的数据量,从而降低网络流量。
- 低服务器资源消耗: 与 Output Buffering 输出缓冲相比,对服务器的 CPU 和内存要求相对较低,特别是在处理大量输出时。
劣势:
- 可能增加CPU使用率: 虽然总体上对服务器资源的影响较小,但启用压缩可能轻微增加 CPU 使用率。
- 兼容性问题: 与某些需要直接操作输出流的扩展可能存在兼容性问题。
2、Output Buffering
而 Output Buffering 输出缓冲是一种常见的 PHP 输出优化手段,将缓冲区中的内容立即发送到浏览器,而不等待页面执行完成后再发送。这可以实现页面内容的实时推送。
通过 ob_start() 函数开启输出缓冲,可以实现对输出的控制。最终可以使用 ob_end_flush() 函数刷新输出缓冲并将内容发送到浏览器。
常见输出缓冲函数 | 功能 | 关闭缓冲区 | 允许继续写入 |
---|---|---|---|
ob_end_flush() | 冲刷并关闭输出缓冲区,发送内容到浏览器 | 是 | 否 |
ob_flush() | 冲刷输出缓冲区,不关闭,允许继续往其中写入数据 | 否 | 是 |
ob_clean() | 清空输出缓冲区,不关闭,使其变为空 | 否 | 是 |
ob_start() | 开启输出缓冲,捕获输出内容 | 否 | 是 |
ob_get_contents() | 获取当前输出缓冲区的内容,但不清空缓冲区 | 否 | 是 |
ob_get_clean() | 获取当前输出缓冲区的内容,并清空缓冲区 | 否 | 是 |
ob_get_length() | 获取当前输出缓冲区的长度(字节数) | 否 | 是 |
ob_implicit_flush() | 设置或取消隐式输出冲刷 | 否 | 是 |
优势:
- 逐段输出: 通过逐段输出结果,可以降低用户等待时间,特别是对于长时间运行的脚本。
- 服务器压力较小: 相对于整体压缩输出,Output Buffering 对服务器的压力较小。
劣势:
- 网络流量未减少: 输出大小未经过压缩,因此并未减少网络流量。
- 增加代码复杂度: 使用 Output Buffering 需要逐段输出,可能增加代码的复杂度。
3. 同时使用的考虑
虽然理论上可以同时使用这两种方法,但实际上可能存在一些冲突。闹着玩下网在开启了 zlib.output_compression
的情况下,调用 ob_end_flush()
失败了。
这主要是因为 zlib.output_compression
会将整个页面内容压缩到一个缓冲区中,需要获取整个输出才能进行压缩,而 ob_end_flush()
试图中途发送这个缓冲区的内容,部分静态内容难以多次输出,导致失败。
因此,最佳实践是根据具体情况选择最适合的方案:
- 如果输出包含大量静态内容,选择开启
zlib.output_compression
。 - 如果输出主要是动态内容,选择使用
ob_end_flush()
。
4. 综合建议关闭其中一个
在选择输出优化方案时,应该明确优化的目标,并根据实际输出内容选择最优方案。合理应用 zlib.output_compression
和 ob_end_flush()
,可以有效提升 PHP 应用程序的输出效率。
4.1、关闭 zlib.output_compression 的三种方法
①、可通过修改 PHP 配置文件,通常名为 php.ini 文件,把 On 改为 Off:
zlib.output_compression = Off
②、如果你使用的是虚拟机,或没有直接访问服务器配置文件的权限,可以尝试在网站根目录的 wp-config.php 文件中添加以下行:
ini_set('zlib.output_compression', 'Off');
③、还可以直接在主题的 functions.php 文件或插件中添加代码,同上。
4.2、关闭 ob_end_flush() 的三个方法
跟上面的一样,全部写一起了,方便查看。
①、php.ini 文件默认值是:output_buffering = 4096,改为 Off 就可以了。
output_buffering = off
②、根目录 wp-config.php 配置文件:
ini_set('output_buffering', 'Off');
③、前面两个设置主要是关闭整个输出缓冲,而不是只关闭 ob_end_flush()
。如果你只想要关闭 ob_end_flush()
而保留其他输出缓冲,可以使用 remove_action
函数在 functions.php 文件中取消关联的动作。如下所示:
remove_action('shutdown', 'wp_ob_end_flush_all', 1);
在移除动作时,后面的数字“1”表示优先级,数字小表示较早执行,而较高的数字表示较晚执行。
总体而言,这两种方法各有用处,但同时使用可能导致效果不佳。通过仔细权衡它们的优劣,可以更好地满足你的应用需求,提供更良好的用户体验。
写完这篇文章,我似乎有一点理解了,又学了一点皮毛。