php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #65115 flush() disables compression from ob_gzhandler
Submitted: 2013-06-24 21:08 UTC Modified: 2017-10-24 06:21 UTC
From: preinheimer@php.net Assigned:
Status: Analyzed Package: Output Control
PHP Version: 5.4.16 OS: linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2013-06-24 21:08 UTC] preinheimer@php.net
Description:
------------
Hi,

Consider the test script. 

One might expect to see: Content-Encoding: gzip in the response headers, but it's not there. If however you comment out that flush() compression is applied. 


As a small amount of background, I work on two tools that help display data from the xhprof extension. They both include flush(); ignore_user_abort(); before doing work to store the profiling information in attempt to have as little impact on the user as possible. Clearly flush() wasn't the safe command I thought it was, as it's having a large affect on the application I'm profiling. 

I'm prepared to write this up in the documentation, but I don't really think this is expected behavior. 



Test script:
---------------
<?php
ob_start('ob_gzhandler');
phpinfo();
flush();



Expected result:
----------------
output compressed

Actual result:
--------------
no compression

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-06-25 04:32 UTC] laruence@php.net
I encountered this problem too.

a workaround is don't use php's gzip handler, use the webserver's
 [2013-06-25 04:37 UTC] laruence@php.net
-Assigned To: +Assigned To: mike
 [2013-06-25 05:30 UTC] mike@php.net
-Status: Assigned +Status: Not a bug
 [2013-06-25 05:30 UTC] mike@php.net
Actually, this is debatable. Flush 
flushes the SAPI's I/O layer and we 
just note that output has 
irreversibly sent. If you want to 
flush the output buffering layer 
you have to use ob_flush prior 
flush.
 [2013-06-25 12:33 UTC] preinheimer@php.net
So if I run:

<?php
ob_start('ob_gzhandler');
phpinfo();
ob_flush();
phpinfo();
flush();

With something like:
curl -H "Accept-Encoding: gzip, deflate" http://test.local/obtest.php

It looks (to me) like the entire output is compressed. The difference in behavior seems, well, necessary to allow the end agent to actually be able to read the output. But confusing from a "different output depending on what happened earlier" standpoint.
 [2013-06-25 13:49 UTC] mike@php.net
Looks like my explanation off the top of my head was not correct.

Which SAPI are you using? Does XHPROF override SAPI methods?
 [2013-06-25 13:56 UTC] preinheimer@php.net
I'm using the apache 2.0 SAPI.

The build of PHP I used to confirm the bug doesn't include XHProf (I wanted a clean build to report on). 

I built with: 
Command 	'./configure' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-mysql=mysqlnd' '--with-gd' '--enable-soap' '--with-libxml-dir=/usr/lib/' '--with-mysql-sock=/tmp' '--with-tidy' '--with-jpeg-dir=/usr/lib/' '--with-xsl' '--with-curl' '--with-zlib' '--enable-gd-native-ttf' '--with-openssl' '--with-mcrypt' '--with-pdo-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-bz2' '--enable-bcmath'
 [2013-06-25 14:05 UTC] mike@php.net
Ok, my explanation pretty much applies to the Apache SAPI.

Due to premature flush()'ing the ob_gzhandler cannot set its headers anymore when it's actually run.
 [2013-06-25 15:40 UTC] mike@php.net
-Status: Not a bug +Status: Open -Type: Bug +Type: Documentation Problem -Assigned To: mike +Assigned To:
 [2013-06-25 15:40 UTC] mike@php.net
flush() causes Apache2 to send it's headers, so the gzhandler cannot send any headers and does nothing any more
 [2013-06-25 15:41 UTC] preinheimer@php.net
-Assigned To: +Assigned To: preinheimer
 [2016-09-28 14:39 UTC] cmb@php.net
I've just had a look at your submitted patch (edit.php.net), Paul.
It seems that it's not complete, because the man page would still
say:

| also doesn't affect PHP's userspace output buffering mechanism.
| This means you will have to call both ob_flush() and flush() to
| flush the ob output buffers if you are using those.

According to what has been said in this ticket this info is wrong.
 [2017-10-24 06:21 UTC] kalle@php.net
-Status: Assigned +Status: Analyzed -Assigned To: preinheimer +Assigned To:
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Thu Feb 21 21:01:26 2019 UTC