php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76571 str_replace fails to replace string in special output buffered environment
Submitted: 2018-07-03 07:22 UTC Modified: 2018-07-03 09:12 UTC
From: roland at nextendweb dot com Assigned:
Status: Not a bug Package: Output Control
PHP Version: 7.2.7 OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: roland at nextendweb dot com
New email:
PHP Version: OS:

 

 [2018-07-03 07:22 UTC] roland at nextendweb dot com
Description:
------------
http://sandbox.onlinephpfunctions.com/code/08eee50202cb2e8ce5b6e849aacb7c5bf37de4ba

Test script:
---------------
<?php
class a {

    private static $bug = 'World';

    public static function parse_output($buffer) {

        $buffer = str_replace('there', self::$bug, $buffer);

        self::$bug = 'What?';

        return $buffer;
    }
}

ob_start('a::parse_output');
echo "Hello there";

$content = ob_get_contents();
ob_clean();

echo $content;
ob_end_flush();

Expected result:
----------------
Hello World

Actual result:
--------------
Hello What?

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-07-03 08:41 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2018-07-03 08:41 UTC] requinix@php.net
http://php.net/manual/en/function.ob-start.php
> The [output_callback] function will be called when the output buffer is flushed (sent) or cleaned (with
> ob_flush(), ob_clean() or similar function) or when the output buffer is flushed to the browser at the end of the
> request.

1. When you echo "Hello there", the callback is *not invoked immediately*
2. ob_get_contents returns "Hello there" back
3. ob_clean sends "Hello there" to the callback, which replaces using "World", but the result is discarded
4. You echo the original "Hello there" again
5. ob_end_flush sends the new "Hello there" to the callback, which replaces using "What?", and the result is sent

Is there a reasonable use case behind this problem? Because otherwise what you should be doing is simply
  ob_start('a::parse_output');
  echo "Hello there";
  ob_end_flush();
 [2018-07-03 09:05 UTC] roland at nextendweb dot com
Well, it makes sense. So I should use the output callback phase parameter to check.
Could you tell me which is the phase which runs only once when the output buffer closed completely?

class a {

    private static $bug = 'World';
    

    public static function parse_output($buffer, $phase) {

        if ( $phase & PHP_OUTPUT_HANDLER_FINAL ){

            $buffer = str_replace('there', self::$bug, $buffer);
    
            self::$bug = 'What?';
        }

        return $buffer;
    }
}
 [2018-07-03 09:12 UTC] requinix@php.net
FINAL is the one.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Dec 27 04:01:29 2024 UTC