php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42334 Error after ob_start causes buffer flush
Submitted: 2007-08-18 01:49 UTC Modified: 2016-09-24 05:05 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: ahaig at penguinmililtia dot net Assigned:
Status: Not a bug Package: Output Control
PHP Version: irrelevant OS: Irrelevant
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: ahaig at penguinmililtia dot net
New email:
PHP Version: OS:

 

 [2007-08-18 01:49 UTC] ahaig at penguinmililtia dot net
Description:
------------
An error that occurs after ob_start() has been called causes the buffer to flush. 

This makes it impossible to appropriately manage output for error handling because sometimes text will randomly be inserted prior to the error output (which means the error output has a full <html></html> tag set, but content gets output before it - often open tags - which messes up tag pairing and display).

I ran into this bug using Smarty templating. Smarty uses ob_get_contents() to grab output from an include() of a compiled template that takes place inbetween ob_start() and ob_end_clean(). Error handling for calls inside the compiled template (which ends up being just combined php and html with multiple <?php ?> pairs) end up with junk before their proper output. 

Reproduce code:
---------------
<?php

ob_start();
echo 'test';
trigger_error('error', E_USER_ERROR);
$output = ob_get_contents();
ob_end_clean();

?>

Expected result:
----------------
I expect to see output from trigger_error() (or any other error php might throw) and nothing else. Non-error output should be buffered and not displayed unless requested. Error output constitutes an exception to normal processing, so should be output. 

The only other logical functioning I can see (although this would not, in my mind, be the preferred functioning) is that the code should output nothing at all, even the error output should go to the output buffer. This would be absolutely consistent for the functions, but would make it impossible to do any error handling inside a buffered section. 

Actual result:
--------------
Echo outputs 'test' and trigger_error outputs an error. 

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-08-19 20:00 UTC] jani@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php


 [2007-08-20 07:50 UTC] jani@php.net
Hint: Try changing the error to E_USER_WARNING instead.
(fatal errors stop script processing and are..eh..FATAL..:)
 [2016-09-23 23:36 UTC] mbutscher at gmx dot de
At least if ob_start is called like e.g.

ob_start(NULL, 0, PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_REMOVABLE);

it should (as far as I understand) forbid to flush the buffer contents even on error.
 [2016-09-24 00:43 UTC] yohgaki@php.net
-Operating System: Mac OS X 10.4.10 +Operating System: Irrelevant -PHP Version: 5.2.3 +PHP Version: irrelevant
 [2016-09-24 00:43 UTC] yohgaki@php.net
Output buffer is flushed when PHP terminates execution. Current PHP cannot catch E_ERROR. This prevents cleaning up buffer, but not E_USER_ERROR. e.g.

set_error_handler(function ($errno, $errstr, $errfile, $errline)
{
    if (!(error_reporting() & $errno)) {
        // This error code is not included in error_reporting
        return;
    }

    switch ($errno) {
    case E_USER_ERROR:
        ob_clean(); //////////////// CLEAN UP BUFFER //////////////////////
        echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
        echo "  Fatal error on line $errline in file $errfile";
        echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
        echo "Aborting...<br />\n";
        exit(1);
        break;

    case E_USER_WARNING:
        echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
        break;

    case E_USER_NOTICE:
        echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
        break;

    default:
        echo "Unknown error type: [$errno] $errstr<br />\n";
        break;
    }

    /* Don't execute PHP internal error handler */
    return true;
});


ob_start();
echo 'test';
trigger_error('error', E_USER_ERROR);
$output = ob_get_contents();
ob_end_clean();
?>

We have not many problematic E_ERRORs in our code base now. Most problematic E_ERRORs are in SOAP module.
 [2016-09-24 01:15 UTC] mbutscher at gmx dot de
One possible way to create a fatal error (ok, only if programmer is lazy)

function foo() ...


if (<usually false>)
    foop();  // spelling error


As long as the if-clause is false the error won't be noticed.
 [2016-09-24 05:05 UTC] yohgaki@php.net
Instead of requesting changes in output buffer, request use of exception or make E_ERROR catchable.
 [2022-02-28 03:58 UTC] freeballin572 at gmail dot com
The following pull request has been associated:

Patch Name: Enhancement: Expose happy path
On GitHub:  https://github.com/php/web-php/pull/406
Patch:      https://github.com/php/web-php/pull/406.patch
 [2022-02-28 04:00 UTC] freeballin572 at gmail dot com
The following pull request has been associated:

Patch Name: usability: link to user profiles also on icon and full name
On GitHub:  https://github.com/php/web-people/pull/14
Patch:      https://github.com/php/web-people/pull/14.patch
 [2022-02-28 04:01 UTC] freeballin572 at gmail dot com
The following pull request has been associated:

Patch Name: Fix some grammatical errors on home page
On GitHub:  https://github.com/php/web-doc/pull/18
Patch:      https://github.com/php/web-doc/pull/18.patch
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 15:01:32 2024 UTC