Jump to content



Latest News: (loading..)

- - - - -

PHP 5.4.X woes - ob_gzhandler always conflicts with zlib.output_compression


  • Please log in to reply
12 replies to this topic

#1   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 21 July 2012 - 12:25 PM

Just loaded PHP 5.4.5 in the hope that ob_gzhandler and zlib.output_compression are playing nicely again .. sadly they are not.

Basically even when zlib.output_compression is off PHP triggers a warning when the ob_gzhandler ob_start() callback function is used.

https://bugs.php.net/bug.php?id=55544&edit=1

So I've done a bit of tinkering with 2.3.2 code in case it helps the 2.4 cause, it's a lot of code for a simple operation but that's what nasty bugs give us!

  // if gzip_compression is enabled, start to buffer the output
  if ( (GZIP_COMPRESSION == 'true') && !headers_sent()
									// Need this in the footer
									&& ($ext_zlib_loaded = extension_loaded('zlib'))
									&& (PHP_VERSION >= '4') ) {
	$zlib = ini_get ( 'zlib.output_compression' ); // an empty string where it doesn't exist or is null
	$ini_set_available = function_exists('ini_set'); // some hosts disable this
	/**
	* @see https://bugs.php.net/bug.php?id=55544&edit=1
	* PHP 5.4.0 - 5.4.5 - ob_gzhandler always conflicts with zlib.output_compression
	*/
	$last_known_bugged_version = '5.4.5';
	$php_bugged_version = ( (version_compare(PHP_VERSION, '5.4.0') >= 0)
	&& (version_compare(PHP_VERSION, $last_known_bugged_version) <= 0 ) ) ? true : false;
	// If zlib is null - an empty string - 0 - or off/OFF we take it as being turned off
	if ( ( ($zlib == null) || ($zlib == '') ) || $zlib == 0 || strtolower( (string)$zlib ) == 'off' ) {
	  /**
	  * No point trying to ini_set if the host has it turned off!
	  * zlib.output_compression was available from 4.0.5
	  */
	  if ( $ini_set_available && (version_compare(PHP_VERSION, '4.0.5') >= 0 ) ) {
		ini_set('zlib.output_compression', 1);
		ini_set('zlib.output_compression_level', GZIP_LEVEL);
	  // If the PHP version is larger than 4.0.4 and it is not a bugged version then we should be ok using the ob_gzhandler callback
	  } elseif ( (version_compare(PHP_VERSION, '4.0.4') >= 0 ) && !$php_bugged_version ) {
		ob_start('ob_gzhandler');
	  } else { // last ditch defence
		include(DIR_WS_FUNCTIONS . 'gzip_compression.php');
		ob_start();
		ob_implicit_flush();
	  }
	} else ini_set('zlib.output_compression_level', GZIP_LEVEL); // It's on so well set the level
	// For use in the footer
	$ini_zlib_output_compression = (int)ini_get('zlib.output_compression');
  } // end gzip compression

Apologies in advance for when the forum destroys the code spacing.

The $last_known_bugged_version = '5.4.5' would have to be changed if we are really unfortunate and the problem persists in 5.4.6

added a file as the spacing did indeed break.

Edited by FWR Media, 21 July 2012 - 12:29 PM.


#2   Juto

Juto
  • Members
  • 369 posts
  • Real Name:Sara
  • Gender:Female

Posted 21 July 2012 - 01:11 PM

Hi Robert, and thanks.
Seems that a lot of things are happening at the same time, first osc v2.3.2... then php5.4.x ... then osc v2.3.3... then... :)

Thanks for being up front and fixing things like this, a common shop owner would else have no idea what's going to break there site.

Sara

#3   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 24 July 2012 - 04:48 PM

Revised version as the other was a "quick fiddle"

  // if gzip_compression is enabled, start to buffer the output
  if ( GZIP_COMPRESSION && !headers_sent()
						  // Need this in the footer
						  && ($ext_zlib_loaded = extension_loaded('zlib')) ) {
	// For use in the footer
	$ini_zlib_output_compression = (int)ini_get ('zlib.output_compression'); // an empty string where it doesn't exist or is null
	$ini_set_available = function_exists('ini_set'); // some hosts disable this
	/**
	* @see https://bugs.php.net/bug.php?id=55544&edit=1
	* PHP 5.4.0 - 5.4.5 - ob_gzhandler always conflicts with zlib.output_compression
	*/
	$last_known_bugged_version = '5.4.5'; // Only here to make clear which version is the bugged one in the code
	$php_bugged_version = ((version_compare( PHP_VERSION, '5.4.0') >= 0 )
	&& (version_compare(PHP_VERSION, $last_known_bugged_version) <= 0)) ? true : false;
	// If zlib is not 1 then it is off
	if ($ini_zlib_output_compression !== 1) {
	  // No point trying to ini_set if the host has it turned off!
	  if ($ini_set_available && (version_compare(PHP_VERSION, '4.0.5') >= 0)) {
		ini_set('zlib.output_compression', 1);
		ini_set('zlib.output_compression_level', GZIP_LEVEL);
	  // If the PHP version is larger than 4.0.4 and it is not a bugged version then we should be ok using the ob_gzhandler callback
	  } elseif ((version_compare(PHP_VERSION, '4.0.4') >= 0) && !$php_bugged_version) {
		ob_start('ob_gzhandler') ;
	  } elseif (version_compare(PHP_VERSION, '4.0.1') >= 0 ) { // last ditch defence
		include(DIR_WS_FUNCTIONS . 'gzip_compression.php');
		ob_start();
		ob_implicit_flush();
	  }
	} else ini_set('zlib.output_compression_level', GZIP_LEVEL); // It's on so well set the level
  } // end gzip compression

File attached. beware the <?php at the start of the file as you don't need or want it.

Attached Files



#4   Harald Ponce de Leon

Harald Ponce de Leon

    Healthy Giraffe

  • Core Team
  • 4,024 posts
  • Real Name:Harald Ponce de Leon
  • Gender:Male
  • Location:Solingen, Germany

Posted 25 July 2012 - 02:15 PM

Hi Robert..

Great catch! A simpler fix for v2.3.3 has been pushed to my github repo at:

https://github.com/haraldpdl/oscommerce2/commit/ab26d82f98422e9a24169403af7f7310df387f5e

What do you think of the simpler fix?

A bug report has also been created to keep track of the bug:

http://forums.oscommerce.com/tracker/issue-468-php-54-ob-gzhandler-and-zlib-output-compression-conflict/
Harald Ponce de Leon

#5   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 25 July 2012 - 02:40 PM

@Harald Ponce de Leon

Yup looks nice and short.

[tiny point] I took an extra line to set $last_known_bugged_version because 5.4.5 is not definately ( but is hopefully ) the last bugged version, just thought it would be easier for a user to change as it's obvious as opposed to a part of the logic

I'm wondering why you aren't turning on zlib.output_compression when it is available and off.


[edit]Oh and you're not checking for 4.0.1+ for the existence of gzcompress nor that ini_set is available which is off on a lot of hosts.

Edited by FWR Media, 25 July 2012 - 02:44 PM.


#6   Harald Ponce de Leon

Harald Ponce de Leon

    Healthy Giraffe

  • Core Team
  • 4,024 posts
  • Real Name:Harald Ponce de Leon
  • Gender:Male
  • Location:Solingen, Germany

Posted 25 July 2012 - 03:00 PM

The PHP bug report is closed and the last comment is from a PHP developer who has pushed a fixed out - I assume this will be fixed in 5.4.6.

Regarding zlib.output_compression, it seems safer to use ob_gzhandler as there have been conflicting reports with enabling it through ini_set, eg:

PHP 4.2 https://bugs.php.net/bug.php?id=17299
PHP 5.4 https://bugs.php.net/bug.php?id=61443
PHP 5.1.1 https://bugs.php.net/bug.php?id=35936
PHP 5.2.6 https://bugs.php.net/bug.php?id=45202

And that's just a quick scan from

https://bugs.php.net/search.php?search_for=output_compression&cmd=display&status=Closed
Harald Ponce de Leon

#7   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 25 July 2012 - 03:21 PM

View PostHarald Ponce de Leon, on 25 July 2012 - 03:00 PM, said:

The PHP bug report is closed and the last comment is from a PHP developer who has pushed a fixed out - I assume this will be fixed in 5.4.6.

I applaud your faith in the PHP group Harald :)

This made me unsure
2012-06-22 - You are right. It seems to be fixed in php-5.4.4-1; no more errors now.

Quote

Regarding zlib.output_compression, it seems safer to use ob_gzhandler as there have been conflicting reports with enabling it through ini_set

Fair enough wasn't aware of that,  with zlib being the preferred method I would still prefer to use @ini_set() and check for false but i can understand why you would go for the ob_start callback.

#8   Harald Ponce de Leon

Harald Ponce de Leon

    Healthy Giraffe

  • Core Team
  • 4,024 posts
  • Real Name:Harald Ponce de Leon
  • Gender:Male
  • Location:Solingen, Germany

Posted 25 July 2012 - 03:34 PM

View PostFWR Media, on 25 July 2012 - 03:21 PM, said:

I applaud your faith in the PHP group Harald :)

This made me unsure
2012-06-22 - You are right. It seems to be fixed in php-5.4.4-1; no more errors now.

The comments Laurence made yesterday in that report are more assuring ;-)

View PostFWR Media, on 25 July 2012 - 03:21 PM, said:

Fair enough wasn't aware of that,  with zlib being the preferred method I would still prefer to use @ini_set() and check for false but i can understand why you would go for the ob_start callback.

There's a note here that states:

Quote

Also note that using zlib.output_compression is preferred over ob_gzhandler().

So far so good, and here it states:

Quote

zlib.output_compression PHP_INI_ALL

Sounds good! But I personally don't know how such a setting can affect the page request during execution and send the correct headers even though the docs says PHP_INI_ALL. That's why I quickly scanned the bug reports and there are several different PHP versions with problems when using ini_set().

Perhaps the preferred manner of using zlib.output_compression is through php.ini, not ini_set().

Edited by Harald Ponce de Leon, 25 July 2012 - 03:37 PM.
Added "during execution" to "..affect the page request.."

Harald Ponce de Leon

#9   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 25 July 2012 - 03:57 PM

View PostHarald Ponce de Leon, on 25 July 2012 - 03:34 PM, said:

Perhaps the preferred manner of using zlib.output_compression is through php.ini, not ini_set().

Yup, I suppose it is not worth further "over analysis" with ob_gzhandler being readily available.

#10   Harald Ponce de Leon

Harald Ponce de Leon

    Healthy Giraffe

  • Core Team
  • 4,024 posts
  • Real Name:Harald Ponce de Leon
  • Gender:Male
  • Location:Solingen, Germany

Posted 26 July 2012 - 02:04 PM

View PostFWR Media, on 25 July 2012 - 02:40 PM, said:

[edit]Oh and you're not checking for 4.0.1+ for the existence of gzcompress nor that ini_set is available which is off on a lot of hosts.

Fixed! Here is the combined commits to be part of the 2.3.3 upgrade guide:

https://github.com/osCommerce/oscommerce2/commit/1d4f5e9d00e88416d1074dd1fe1a76e1d9ac88b2
Harald Ponce de Leon

#11   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 26 July 2012 - 03:00 PM

View PostHarald Ponce de Leon, on 26 July 2012 - 02:04 PM, said:

Fixed! Here is the combined commits to be part of the 2.3.3 upgrade guide:

Very neat, nice!

#12   Harald Ponce de Leon

Harald Ponce de Leon

    Healthy Giraffe

  • Core Team
  • 4,024 posts
  • Real Name:Harald Ponce de Leon
  • Gender:Male
  • Location:Solingen, Germany

Posted 17 August 2012 - 12:16 PM

View PostFWR Media, on 25 July 2012 - 03:21 PM, said:

I applaud your faith in the PHP group Harald :)

It worked out this time! In the PHP 5.4.6 changelog:

Quote

Zlib; Fixed bug #55544 (ob_gzhandler always conflicts with zlib.output_compression).

:thumbsup:
Harald Ponce de Leon

#13   FWR Media

FWR Media
  • Community Sponsor
  • 6,839 posts
  • Real Name:Robert Fisher
  • Gender:Male
  • Location:Stowmarket - Suffolk - UK

Posted 17 August 2012 - 12:51 PM

@Harald Ponce de Leon

View PostHarald Ponce de Leon, on 17 August 2012 - 12:16 PM, said:

It worked out this time! In the PHP 5.4.6 changelog:

Excellent, one less compatibility issue to worry about!