Search code examples
phpbufferingglobal

Inserting output into page after document has been executed


In PHP have a situation where I need the page to be mostly executed, but have an item inserted into the output from that page.

I think output buffering may be of some help, but I can't work out how to implement it in my situation.

My code looks like this:

//this document is part of a global functions file

function pageHeader (){

    //I'm using $GLOBALS here because it works, however I would really rather a better method if possible
    $GLOBALS['error_handler'] = new ErrorHandler(); //ErrorHandler class sets a function for set_error_handler, which gets an array of errors from the executed page

    require_once($_SERVER['DOCUMENT_ROOT'].'/sales/global/_header.php');

    //I would like the unordered list from ->displayErrorNotice() to be displayed here, but if I do that the list is empty because the list was output before the rest of the document was executed
}

function pageFooter (){

    $GLOBALS['error_handler'] ->displayErrorNotice(); //this function displays the errors as an html unordered list

    include($_SERVER['DOCUMENT_ROOT']."/sales/global/_footer.php");
}

Most pages on the site include this document and use the pageHeader() and pageFooter() functions. What I am trying to achieve is to put an unordered list of the PHP generated errors into an HTML list just at a point after _header.php has been included. I can get the list to work as intended if I put it in the footer (after the document has been executed), but I don't want it there. I guess I could move it with JS, but I think there must be a PHP solution.

UPDATE

I'm wondering whether a callback function for ob_start() which searches the buffer by regex where to put the error list, and then inserts it will be the solution.

UPDATE 2 I have solved the problem, my answer is below. I will accept it in 2 days when I am allowed.


Solution

  • Worked it out finally. The key was to buffer the output, and search the buffer for a given snippet of html, and replace it with the unordered list.

    My implementation is like this:

    function outputBufferCallback($buffer){
    
        return str_replace("<insert_errors>", $GLOBALS['error_handler']->returnErrorNotice(), $buffer);
    }
    
    function pageHeader (){
    
        ob_start('outputBufferCallback');
        //I'm using $GLOBALS here because it works, however I would really rather a better method if possible
        $GLOBALS['error_handler'] = new ErrorHandler(); //ErrorHandler class sets a function for set_error_handler, which gets an array of errors from the executed page
    
        require_once($_SERVER['DOCUMENT_ROOT'].'/sales/global/_header.php');
    
        echo '<insert_errors>'; //this snippet is replaced by the ul at buffer flush
    }
    
    function pageFooter (){
    
        include($_SERVER['DOCUMENT_ROOT']."/sales/global/_footer.php");
        ob_end_flush();
    }