WordPress.org

Make WordPress Core

Opened 7 years ago

Last modified 3 months ago

#22430 reopened defect (bug)

wp_ob_end_flush_all bug when zlib.output_compression = On

Reported by: Matthias Reuter Owned by:
Milestone: Awaiting Review Priority: normal
Severity: major Version: 2.8
Component: General Keywords: has-patch needs-testing
Focuses: Cc:
PR Number:

Description

When zlib.output_compression is set to On, the function wp_ob_end_flush_all throws the following error:

Notice: ob_end_flush() [ref.outcontrol]: failed to delete buffer zlib output compression in /wp-includes/functions.php on line 2683

You can see this error e.g. when opening /wp-login.php in browser.

Critical Issue related to this bug: it also affects usage of /wp-admin/customize.php - the preview results in a blank page. Seems that the error avoids ajax snippets from getting loaded succesfully.

Hotfix is replacing in /wp-includes/functions.php

function wp_ob_end_flush_all() {
	$levels = ob_get_level();
	for ($i=0; $i<$levels; $i++)
		ob_end_flush();
}

with

function wp_ob_end_flush_all() {
	//$levels = ob_get_level();
	//for ($i=0; $i<$levels; $i++)
	//	ob_end_flush();
}

This issue occurs in all browsers (ie,ff,opera, etc) with both latest versions of WordPress, 3.4.2 and latest nightly build on a LAMP system with PHP Version 5.3.10-1~dotdeb.0.

PHP zlib settings:

Directive	Local Value	Master Value
zlib.output_compression	On	Off
zlib.output_compression_level	5	-1
zlib.output_handler	no value	no value

Attachments (1)

22430.patch (478 bytes) - added by openwrite 4 months ago.

Download all attachments as: .zip

Change History (17)

#2 @SergeyBiryukov
7 years ago

  • Keywords needs-patch removed
  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Status changed from new to closed
  • Version changed from trunk to 2.8

Going to close as a duplicate of #18525, which has patches.

The same notice is mentioned in ticket:18525:9.

#3 @Matthias Reuter
7 years ago

  • Resolution duplicate deleted
  • Status changed from closed to reopened

Hi Sergey,

thanks for relating the other tickets to this issue. Currently WordPress per default is not compatible with zlib enabled. While Server-Side-Compression is recommened by search engines and most browsers, the other tickets linked by you recommend either disabling zlib or inserting a hotfix.

I don't want to live with a hotfix over the next years which needs to be re-applied manually with every WordPress update.

I would recommend dropping support for PHP 5.2 (or even check wether PHP 5.3 is on server) to avoid that a compatibility function (wp_ob_end_flush_all()) for PHP 5.2 produces new errors on PHP 5.3 installations with zlib enabled.

So I hope that the developers of WordPress will fix this issue and don't let me hotfix that the next years until PHP 5.2 support is finally dropped.

Kind regards,

Matthias

#4 @nacin
7 years ago

  • Resolution set to duplicate
  • Status changed from reopened to closed

Rather than hacking core, try this one-line plugin on for size:

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

We may be at the point where we can eliminate this from core. I'll look into it at the start of the 3.6 cycle. Closing this as a duplicate of #18525 makes sense, because that ticket is reporting the same problem. You disagree with the solution, and that's completely fine, but you should voice it there. (For what it's worth, I also don't like the solution, which is why I myself have not committed it.)

#5 @Matthias Reuter
7 years ago

Wow, nacin, this fix works great and I don't need to touch the core - perfect :)

#6 @daveagp
7 years ago

I found nacin's fix to work for me as well. I was experiencing problems with ajax (regardless of whether I used WP's ajax hooks, or I directly called a .php from ajax and had the php load wp-load.php). Thanks!

#7 @Sam_a
5 years ago

Thanks @nacin. I've seen this bug for years and I hope it's eventually fixed in core.

#8 @selnomeria
5 years ago

NO!
in documentation comments ( https://core.trac.wordpress.org/browser/tags/4.2.2/src/wp-includes/functions.php#L3279 ) they say that it is needed for PHP 5.2 .

So, i dont know, if other PHP versions doesnt need that function.. I dont know.

Last edited 5 years ago by selnomeria (previous) (diff)

#9 @carasmo
7 months ago

  • Resolution duplicate deleted
  • Status changed from closed to reopened

I'm in WordPress 5.2.2 and PHP 7.1.30 and I'm getting this error at the bottom of all the pages when debug is on. I need it on this is a staging site for troubleshooting. I can't find any help on this very old issue. I've turn off all plugins one by one all the standard troubleshooting and zilch. Switched to 2019, also doesn't address it.

Thanks!

Notice: ob_end_flush(): failed to send buffer of zlib output compression (0) in /home/xxx/staging/wp-includes/functions.php on line 4339

#10 @bobbingwide
5 months ago

I've recently noticed this where my hosting ( TSOhost ) have switched to PHP 7.3 and have set zlib.output_compression=on by default, and where my sites have WP_DEBUG true.

Is it not possible to detect the PHP ini setting and not attach the wp_ob_end_flush_all action function to shutdown when it's set?

Or alter the function to do nothing. e.g.

if ( ini_get( 'zlib.output_compression') ) {
  return;
}
Last edited 5 months ago by bobbingwide (previous) (diff)

This ticket was mentioned in Slack in #core by bobbingwide. View the logs.


5 months ago

#12 @SergeyBiryukov
5 months ago

  • Milestone set to Awaiting Review

#13 @openwrite
4 months ago

I've been running into this error quite a bit recently during plugin development. The fix I've put in place is similar to the suggestion from @bobbingwide (I actually just submitted it as a WordPress plugin, before finding this), and reads as follows:

//define fixed function
function wp_ob_end_flush_all_fixed() {
        $start = (int) ini_get('zlib.output_compression');
        $levels = ob_get_level();
        for ( $i = $start; $i < $levels; $i++ ) {
                ob_end_flush();
        }
}

//remove original callback
remove_action('shutdown', 'wp_ob_end_flush_all', 1);

//add fixed callback
add_action('shutdown', 'wp_ob_end_flush_all_fixed', 1);

My rationale was that when zlib.compression is on, the starting buffer level should always be treated as 1. This allows all additional buffers to be cleared and doesn't impact installs where zlib is off. There might be reasons I'm not aware of that would cause issues in other scenarios, but since putting this fix in place I haven't experienced any further issues.

EDIT: Whilst the code comments suggest "wp_ob_end_flush_all" is only executed on php 5.2, I've found it executing on all versions up to and including 7.3.

Last edited 4 months ago by openwrite (previous) (diff)

@openwrite
4 months ago

#14 @openwrite
4 months ago

  • Keywords has-patch needs-testing added

#15 @normancates
3 months ago

I've been having this error on practically every site I've ever used.

It certainly seems to be related to zlib compression being on.

And has been present as a problem for MANY years.

I posted this the other day, and got refered to Bug Trac. And found this issue. So yes, please can WP implement a fix to this problem. It's a common problem that seems easy to fix.


Regarding the wp_ob_end_flush_all() function. I've been trying to fix this for ages.

Recently in some frustration I subtracted 1 from the $levels variable.

function wp_ob_end_flush_all() {
print wp_debug_backtrace_summary();
$levels = ob_get_level();
for ( $i = 0; $i < $levels-1; $i++ ) {
ob_end_flush();
}
}

And the warning went away. This seems MAD if this is ACTUALLY the solution. Because I see a lot of frustrated and puzzled people having this problem.

I decided to dig a little deeper and find the PHP function ob_end_flush()

https://www.php.net/manual/en/function.ob-end-flush.php

On this page there are some user comments (from many years ago to be sure) about zlib compression increasing the level by 1?

I certainly have zlib compression turned on for my sites.

And so do most people who are having this problem. (And no, turning off compression is NOT an acceptable option, despite all the people who suggest it.)

Then I found this little gem under Examples:

<?php
while (@ob_end_flush());
?>

So, I decided to try it in the WP function

function wp_ob_end_flush_all() {
while (@ob_end_flush());
}

And still, no warnings are being thrown up.

IS this a legitimate fix? IS there anything to say this is a problem to do?

I realise this is just suppressing the warning for this command. Is that a problem? My understanding is that this may slow execution down slightly?


I just wanted to add my voice to ask to get this fixed.

#16 @autotutorial
3 months ago

To understand what happens, let's take a step back to the source of this error

Notice: ob_end_flush() [ref.outcontrol]: failed to delete buffer zlib output compression in /wp-includes/functions.php on line 2683

ob_end_flush() can return false and issue Notice when something goes wrong. the zlib buffer cannot be closed, rather than relying with ob_get_level() a code can be processed with ob_list_handlers() which indicates whether outup_buffering (output_buffering INI ALL or ob_start with or without callback) is in use Only one compression buffer can exist at a time.
With zlib.output_compression enabled, what does ob_list_handlers() return? please you can do a test because I can't but I would like assistance in the solution.

Last edited 3 months ago by autotutorial (previous) (diff)
Note: See TracTickets for help on using tickets.