I've tried absolutely everything!! How can I flush the output buffer in CodeIgniter from within either my controller or my view?? They use some weird double/fake output buffer or something. Grrr!

Recommended Answers

All 14 Replies

I got the following to work (in my controller). Why it works, I have no clue. I just played around a bunch ...

// Process this right away
echo $this->load->view('foo', array(), true);
echo ob_get_clean();
flush();
ob_start();

It worked whether or not I had ob_start() but I assume I need to start it up again??

OK, so I think I'm confusing ob_get_clean() with ob_get_flush(). If I'm correct, I'm not turning off output buffering in my code so that's why I don't need to call ob_start(). Right ...?

Oh, nevermind, I confused myself even more.

Updated code (this is now in a function called by a controller method):

$CI =& get_instance();

if (ob_get_length() > 0)
{       
    // Process this right away
    echo $CI->load->view('foo', array(), true);
    ob_end_flush();
    ob_start();
}
else
{
    $CI->load->view('foo', array());
}

Err ... I forgot to call flush()

Also, now I've replaced lines 7/8 above with

if (ob_end_flush())
{
    ob_start();
}
flush();

What is the purpose of flushing the output buffer in a controller? Are you trying to use codeigniter in an HMVC fasion and include one controller within another?

Member Avatar for iamthwee

I thought you can just include a header file. And with that at the top put ob_start. Then include this header on every page.

Just want to point out that it works. I'm just confused why it works :)

Instead of sending the entire document to the web browser as soon as it's ready, I am trying to flush the output right after generating the HEAD portion of the HTML document, so that all of the external css/javascript files can be fetched by the client at the same time as php is still processing the bulk of the page.

commented: This is EXACTLY one of the things I want to make sure works out well in my project. +0

Thank you for posting this. This has allowed me to show a "please wait" while waiting for several long sql lookups that are connecting to multiple databases worldwide and without having to use AJAX.

Oh, glad to hear it was useful to someone else! :)

It took me a few minutes to fully grasp exactly what code was suggested, and what code was patched afterwards (and why).

This is almost exactly the process I came on here wanting to learn about.

I signed on to this forum because it's a very well-written site (I can tell).

And because it runs on CodeIgniter, there is special knowledge I knew I could glean from a trailblazer of using CodeIgniter on a site using active forum interaction databases (multiple interactions happening often, AJAXy stuff, etc.), and with all that demand on the servers, optimizing the output, getting data presented to the view as soon as possible.

I also aim at minimalism, and the headers usually show up within the first X amount of data which goes out 'first', presenting a better 'illusion' of 'fast' (read: optimized). I grew up with a bit of retro BBSes and was a part of the Ocean State Free Net.

So, if I can imagine any site as showing up "well-rendered" (if you're from this era, think of the countless pages filled with [IMAGE], [], [FRAME], Scripts that RELY on JavaScript, Pages that RELY on CSS, etc) in the classic Lynx text browser, it passes my personal standards test. I don't know if anything like the "AnyBrowser" campaign exist any more, but I hold myself to these standards for my work. I learned how to code back when it was just HTML and /CGI-BIN/ was plastered all over the Internet. I assume sites that relied on these were one of the beginnings of Web 2.0: Interactive Internet.

Anyways, what I've learned is that the most important thing in the current era is the 'illusion' of 'fast'.

Give the user something fast, easy, and give them a sense of immediate action until 'actual' useful data can be rendered on their device (the VIEW-er they are using to view your site on). There

The effect is the time from when a user's requests are sent from their device, through their Internet to the time they get useful data back.

Remember, in international terms, this means that data can be a LOT slower than ANY of us are used to having with broadband -- knock your brain back to the 1990s -- people in many countries are still using small cellular phones with tiny screens, which use the web at dial-up, 128K, DSL, and satellite speeds... so, until when 'useful' data can be delivered, many people are waiting for their device to give them some output (all these the OB functions, which you are Output-Buffering on your end).

These include HTTP headers (100 OK, 404 Error, etc), document titles (which will be used for easy-to-read bookmarks in this day and age, on most mobile devices a terse title works best), quick navigation data, <H1> headings, site logo, etc, and most importantly, links to HTML that let them 'fast navigate' if they landed somewhere inconvenient (reliable links, people will hover on -- accidental clicks need a 'Fast Undo' or to make a 'Back' feature just as useful by returning you to a page that is easy to re-load and get back to the spot you -meant- to click on.

So, not only was your "confusing yourself" content useful, but it was almost one of those 'tutorials' that I came on here to hunt down or ask about from Thou, Dani.

It took me a little bit of time to figure it out.

I have been trying to understand how to make this work, and this entire tutorial above seems to work to get that 'useful' data out there, and get the external files 'requested' (depending on the browser) such as CSS, JS, AJAXy stuff, and giving the "Web 2.0" background program time to work on finishing the rest of its code execution (microseconds, really, while it takes the 'new' data someone has input, and routes it) while the browser is 'bogged down' with the work of double-checking files against cache on the user-end, double-checking server cache files VS unique requests, getting the actual files sent from server to user (dispatch?), etc.

So, the final code looks something like this:

$CI =& get_instance();
if (ob_get_length() > 0) {       
    // Send this to the output buffer 
    echo $CI->load->view('foo', array(), true); 
    if (ob_end_flush()) {
        ob_start();
    }
    flush();
}
else
{
$CI->load->view('foo', array()); // If there wasn't anything in the O.B.
}

I think this means that somewhere in CodeIgniter's Output class, there is an ob_start().

So, when you call ob_end_flush(), it's sending whatever CodeIgniter has stored up using $this->load->view, right?

Do you use $CI instead of $this using get_instance() because CodeIgniter supplements your main program designs?

Specifically, would it benefit from patching a different value into the output_buffer_size (not the correct value name) in CodeIgniter (instead of 4K of data by default) -- and would it function if ob_get_length() was a larger value than 0 -- would that last bit of data never get sent (and die in an output_buffer)?

However, my main question (to anyone) ends up being this:
WHY do we flush() afterwards, too?

Thought/Question/Theory:
Is it because flush() takes ALL buffered output, which was only flushed partway (to the main buffer that the final call to flush() ends?

Or is there another reason?

Well, this may have worked, but with CI 3 this trick does not work. You wait for all processing done then you see all output at once.

Hi Karl,

So sorry I'm late to see your response here. It's possible it's not CodeIgniter that is causing it to not work but rather your server configuration.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.