Make WordPress Core

Opened 12 years ago

Closed 10 months ago

#22430 closed defect (bug) (duplicate)

wp_ob_end_flush_all bug when zlib.output_compression = On

Reported by: matthias-reuter's profile Matthias Reuter Owned by:
Milestone: Priority: normal
Severity: normal Version: 2.8
Component: General Keywords: has-patch needs-testing
Focuses: Cc:

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 5 years ago.

Download all attachments as: .zip

Change History (20)

#2 @SergeyBiryukov
12 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
12 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
12 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
12 years ago

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

#6 @daveagp
11 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
10 years ago

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

#8 @selnomeria
9 years ago

NO!

removing that action is not a good solution, because that ACTION is Wordpress Core action, and it might be needed, so, when you remove that, you might mess up something.

Version 0, edited 9 years ago by selnomeria (next)

#9 @carasmo
5 years 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 years 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 years ago by bobbingwide (previous) (diff)

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


5 years ago

#12 @SergeyBiryukov
5 years ago

  • Milestone set to Awaiting Review

#13 @openwrite
5 years 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 5 years ago by openwrite (previous) (diff)

@openwrite
5 years ago

#14 @openwrite
5 years ago

  • Keywords has-patch needs-testing added

#15 @normancates
5 years 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.

Last edited 4 years ago by SergeyBiryukov (previous) (diff)

#16 @autotutorial
5 years 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 5 years ago by autotutorial (previous) (diff)

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


4 years ago

#18 @normancates
4 years ago

Hi ya. I was wondering about the state of this fix. I still get this error on new wordpress sites.

So now I have a micro plugin that I just install that does the fix that @openwrite noted at #13 above.

As far as I can tell, it quells the problem, and doesn't introduce other problems...

How can we help get this into core? I honestly don't understand why it's been 9 years since this first report. Or to be charitable, 20 months since @openwrite supplied a possible solution.

#19 @swissspidy
10 months ago

  • Milestone Awaiting Review deleted
  • Resolution set to duplicate
  • Severity changed from major to normal
  • Status changed from reopened to closed

Still a duplicate of #18525, let's continue the discussion there.

Note: See TracTickets for help on using tickets.