注意:ob_end_flush():在zlib输出压缩(1)的缓冲区发送失败。

32

我的本地主机上没有任何问题,但当我在服务器上测试我的代码时,每个页面的末尾都会显示这个通知。

我的代码:

<?php
ob_start();
include 'view.php';

$data = ob_get_contents();
ob_end_clean();
include 'master.php';
ob_end_flush();  // Problem is this line
13个回答

43

我不建议完全禁用wp_ob_end_flush_all()函数,也绝对不会关闭php.ini文件中的zlib.output_compression。以下是更好的方法,替换导致问题的源代码,并保留底层功能:

/**
 * Proper ob_end_flush() for all levels
 *
 * This replaces the WordPress `wp_ob_end_flush_all()` function
 * with a replacement that doesn't cause PHP notices.
 */
remove_action( 'shutdown', 'wp_ob_end_flush_all', 1 );
add_action( 'shutdown', function() {
   while ( @ob_end_flush() );
} );

更多关于原因和为什么这可能是最好的方法的详细信息可以在此处找到:WordPress ob_end_flush()错误的快速修复


1
在我的情况下,在WordPress网站上,我可以确认这种方法对页面速度有积极的影响,而不是@alexg的方法。 - Dvaeer
1
你的方法对我没有起作用,Kevin。把你的代码放在我的子主题的functions.php、主题的functions.php和wp-includes中的一个中。我觉得你的文章有些地方不够清楚 - 例如我们是否要删除wp-includes/functions.php中的wp_ob_end_flush_all函数? - stigzler
谢谢分享这个。它对我有用。 - Umar Niazi
我将这段代码直接复制粘贴到我的WordPress插件的index.php文件中,错误消失了!太神奇了,谢谢。 - Spinstaz
现代PHP会自动刷新所有现有的缓冲区,因此完全可以安全地完全删除此函数。这个解决方案也应该可以正常工作。有关更多信息,请参见我的上面的评论。 - Brian C
显示剩余2条评论

39

WordPress试图在关闭时刷新输出缓冲区,但由于您已经调用了ob_end_flush(),因此失败了。

您应该能够保持压缩状态,只需取消挂钩刷新操作即可:

remove_action( 'shutdown', 'wp_ob_end_flush_all', 1 );

你现在可以手动调用ob_end_flush(),并保持zlib压缩。


2
我们为什么需要删除调用 wp_ob_end_flush_all() 的原因尚不明确,因为它实际上使用了缓冲级别(通过 ob_get_level() - 请参见 此处的代码)。它应该自动检测级别并运行正确数量的 ob_end_flush() 调用,但实际上却多执行了一个。这似乎是一个错误! - Brian C
将此代码添加到您的子主题function.php文件中 - 对我来说起作用了。 - DevWL
1
使用此解决方案时,经常会出现以下通知:“ob_end_flush():无法删除和刷新缓冲区。没有要删除或刷新的缓冲区。”并且无法回答一个基本问题:为什么这种情况不会发生在每个WordPress安装上,也不会发生在每个服务器上? - bluantinoo
你提到了“你应该能够保持压缩”,这是什么意思? - Pvria Ansari
@PouriaAnsari 我的意思是,如果你移除那个操作,问题就会解决,你不需要像AliN11在另一个回答中建议的那样在Web服务器级别禁用zlib压缩。但也可以看看KevinLeary的回答。 - alexg
1
经过一些时间,似乎这个错误是由于服务器PHP选项zlib.output_compression打开造成的,因为它创建了一个内部缓冲区,从而在某种程度上搞乱了ob_get_level()。PHP本身会在关闭时自动刷新所有现有的缓冲区,因此不再需要wp_ob_end_flush_all()。它曾经是过去PHP 5.2兼容性问题所需的,对大多数服务器来说都很好,因此没有被删除。当WordPress醒来并删除该函数时最好,但目前删除关闭操作也是可以的,并且非常安全。 - Brian C

11

php.ini 中关闭 zlib.output_compression 后问题得以解决。

zlib.output_compression = Off


23
我认为关闭gzip压缩不是一个有效的解决方案。 - Swen
3
我同意@Swen的观点。输出压缩(无论是deflate还是gzip)几乎总是对SEO基准有积极的影响,包括Google的PageSpeed insights。禁用它可能会损害您在搜索结果中的排名,因为它会增加移动用户的加载时间。 - Adambean
@Adambean ... 是的,但是gzip解压缩几乎总是在Web服务器级别上开启的,因此认为PHP预压缩可能是不必要的,不是吗? - scott8035
这不是一个解决方案;从网站中删除压缩只是懒惰和可怕的,使用上述其他可行的解决方案之一。 - Brian C

3

出于安全考虑,您应该始终在实时网站上禁用前端错误 - 无论如何。

如果您想隐藏WordPress中的错误并获取错误日志以供检查,可以在wp-config.php文件中执行以下操作:

Original Answer翻译成"最初的回答"

// Enable WP_DEBUG mode
define( 'WP_DEBUG', true );

// Enable Debug logging to the /wp-content/debug.log file
define( 'WP_DEBUG_LOG', true );

// Disable display of errors and warnings
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

PS: 如果您想使用alexg提供的remove_action代码,remove_action('shutdown', 'wp_ob_end_flush_all', 1); 您需要将其放置在主题的functions.php文件中。

PPS: 您还可以尝试在wp-config.php文件中使用define(‘WP_MEMORY_LIMIT’,’1024M’); - 但是,请注意不要分配过多,因为这会影响WordPress前端,如果页面同时访问太多,您将面临内存不足的风险。

最初的回答:

如果您想使用alexg提供的remove_action代码,您需要将其放置在主题的functions.php文件中。另外,您还可以在wp-config.php文件中使用define('WP_MEMORY_LIMIT','1024M')来尝试解决问题,但请注意不要分配过多内存,以免影响WordPress前端并面临内存不足的风险。

2
我发现其中一个客户的 WP 网站出现问题是由于某个特定的插件引起的。
在这种情况下,问题是由 "NextGEN Gallery" 插件引起的,但奇怪的是,简单地停用和激活插件就解决了问题。
对于其他遇到此问题的人来说,值得寻找可疑的前端插件,并尝试相同的方法。如果您发现问题在恶意插件被重新激活后又会出现,请向插件作者报告问题。

插件(WP Smush)似乎也给我带来了问题。尽管删除并重新安装它可以解决问题,而不是禁用/启用。 - user5589998

1

只需将以下内容添加到主题的functions.php文件中:

remove_action( 'shutdown', 'wp_ob_end_flush_all', 1 );

0
另一个情况是:
我在我的实际网站上收到了这个通知,但在本地主机和演示/测试网站上没有收到,尽管演示网站与实际网站位于同一服务器上。
事实证明,在实际网站上未激活zlib扩展,这导致了该通知。一旦激活了zlib扩展,通知就不再出现。因此,不需要进行代码修复

0

这个错误可能是由于没有关闭?>标签引起的。我在遇到“插件在激活期间生成了X个意外输出字符”的错误后来到这里,然后启用了调试。我将index.php中的包含文件缩小到与/不与错误一起使用的目标文件。然后我进入那个文件,并使用PHP标签关闭了该文件,因为该文件中有许多函数。之后就可以正常工作了。


0
我尝试了一种蛮力方法,它起作用了(虽然我对此不满意,但希望这可以帮助某些人):
/wp-content/themes/<theme_directory>/functions.php的最后一行(显然是在php闭合标记“?>”之前),添加以下行:
ob_get_clean();

0

只需在关闭挂钩上使用您的代码,并使位置更早 默认的ob_end_flush()将识别您的输出并将其刷新

    add_action('shutdown', 'your_code', 0);
function your_code(){
/* Your Code Goes here */
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接