EllisLab text mark
Advanced Search
1 of 2
1
   
CI 1.7 output buffer broken (for Controller->_output)
Posted: 30 October 2008 10:45 AM
Joined: 2007-11-14
37 posts

Somehow only views are buffered, content echo-ed is not buffered. Test code:

class Test extends Controller {

  
function Test() {
    parent
::Controller();
  
}

  
function index() {
    
echo 'index function';
  
}
  
  
function _output($output{
    
echo 'test';
  
}

Using $this->load->view() will work, as long as you don’t use echo $this->load->view($param1, $param2, true);

Of course everything can be done just by loading views, but I still have some dirty code that uses more than just views…
Regards,

Michael

 
Posted: 30 October 2008 11:04 AM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2008-01-07
2507 posts

CodeIgniter does not use the native PHP output buffer.  All view contents are stored in a variable instead.  This variable is passed to the _output function.

You can easily add your own output to the CI buffer though:

ob_start();
echo 
'a';
echo 
'b';
echo 
'c';

$buffer ob_get_contents();
ob_end_clean();

$this->output->append_output($buffer);

// OR
$o 'a';
$o .= 'b';
$o .= 'c';

$this->ouput->append_output($o); 

Hope that helps.

 Signature 
 
Posted: 30 October 2008 11:29 AM   [ # 2 ]   [ Rating: 0 ]
Joined: 2007-11-14
37 posts

Why isn’t codeigniter using a native php output buffer, or any real output buffer? Seems to me that a function called _output with $output as parameter should receive all output… Also from this I would understand that caching wouldn’t work when echoing, and if it does why isn’t the same data that’s written to cache passed as parameter to the _output function? I’d like some confirmation that current behaviour is as expected…
Regards,

Michael

 
Posted: 30 October 2008 11:39 AM   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2008-01-07
2507 posts

I can’t tell you why they do it this way, but I do know that I’ve used it to my advantage multiple times.  Particularly for downloads and async requests.

The caching documentation is pretty clear on this though:

Warning: Because of the way CodeIgniter stores content for output, caching will only work if you are generating display for your controller with a view.

 Signature 
 
Posted: 30 October 2008 12:02 PM   [ # 4 ]   [ Rating: 0 ]
Joined: 2007-11-14
37 posts

I’m currently converting all my pages to get rid of the echos, some pages however don’t use views at all right now (written in a few hours, work, so left untouched after that). If anyone else runs into this problem, it’s always possible to have a view that just echoes content and then repalce all your echoes with view-loading…
Regards,

Michael

 
Posted: 30 October 2008 01:06 PM   [ # 5 ]   [ Rating: 0 ]
Joined: 2008-01-24
163 posts

I wrote a quick function for bypassing the view but still getting into the output.

function bypass_view($rushtml)
    
{
        ob_start
();
        echo 
html_entity_decode($rushtml);
        
// PHP 4 requires that we use a global
        
global $OUT;
        
$OUT->append_output(ob_get_contents());
        @
ob_end_clean();
    

Just fill $rushtml with your entity-encoded html;

 
Posted: 30 October 2008 01:53 PM   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2008-01-07
2507 posts

@Beemr, why are you buffering the output for one echo?

// PHP 4 requires that we use a global
global $OUT;
$OUT->append_outputhtml_entity_decode($rushtml) ); 
 Signature 
 
Posted: 30 October 2008 03:40 PM   [ # 7 ]   [ Rating: 0 ]
Joined: 2008-01-24
163 posts

Honestly, I can’t remember rolleyes , but I think that I was considering the Template_Inheritance_Helper at the time, which made use of the output buffer to create Django-style templates.  It was a neat helper, but I ultimately decided it was overkill versus the just-then-released multiple view loader.

You are right, the ob is unnecessary here.

 
Posted: 30 October 2008 03:49 PM   [ # 8 ]   [ Rating: 0 ]
Joined: 2008-01-24
163 posts

Sure enough.  The function should be:

function bypass_view($rushtml)
    
{
        
// PHP 4 requires that we use a global
        
global $OUT;
        
$OUT->append_output(html_entity_decode($rushtml));
    

Thanks for the optimization, Inparo

 
Posted: 30 October 2008 06:52 PM   [ # 9 ]   [ Rating: 0 ]
Joined: 2007-11-14
37 posts

I could wrap that up into my layout controller, but I still think the CodeIgniter behaviour is wrong… And I’m still waiting for a CodeIgniter dev to answer if this is indeed expected behaviour and if it will always be this way (I for one can understand that people also want to have pages they ‘echo’ cached…).

 
Posted: 30 October 2008 07:10 PM   [ # 10 ]   [ Rating: 0 ]
Joined: 2008-01-24
163 posts

I think that their intention is to keep all echoes within the view file, and so support the MVC principle of separation.

My only gripe with the view loader is that it is strictly linear.  If you want to be able to wrap a div around different combos of modules, then you are forced to clutter your view folder with a bunch of 12-character files.  That’s why I wrote a render library.  It lets me set up a wrap of tags, an opening of tags, or a closing of tags around a view file.

 
Posted: 31 October 2008 03:38 AM   [ # 11 ]   [ Rating: 0 ]
Joined: 2007-11-14
37 posts

I think that they just haven’t thought about it. Not too long ago it wasn’t possible to load multiple views anyway, so everyone had to echo. That meant they couldn’t cache the page if someone was using more than one view. I don’t really care about small view files, I actually have a success, warning and error view which all contain just <div class=“success|warning|error”>$message</div> so I can easily show consistent errors and warnings. I do however care about having to do useless stuff, like loading a header and title in about every function, wehn solving that I ran into the issue this bug is about.
Regards,

Michael

 
Posted: 31 October 2008 04:37 AM   [ # 12 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

I do however care about having to do useless stuff, like loading a header and title in about every function, wehn solving that I ran into the issue this bug is about.

The Views system in CodeIgniter is THE way to present output to the client; THE way. So, when you decide to step out of this foundational convention, you are going to end up circumventing a lot of other things in CI. I have this feeling that you come up on these problems of logic and become frustrated that CI cannot solve your problem. The best experience with a framework can only be had if either your buy 100% in to its conventions, or you become familiar enough to know how to least destructively subvert the conventions, when it serves well to do so.

There are many ways to get global actions to happen on each request (like filling out a portion of the page that has nothing to do with the active controller—sidebars, headers, footers, etc.) Scour the forums and Wiki for specifics.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 31 October 2008 04:41 AM   [ # 13 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

I think that they just haven’t thought about it.

EllisLab is set to release the much anticipated version 2.0 of its immensely popular ExpressionEngine CMS, and it’s built 100% on CI (perhaps even on this latest version, 1.7).

I think they’ve thought about it.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
Posted: 31 October 2008 12:32 PM   [ # 14 ]   [ Rating: 0 ]
Joined: 2007-11-14
37 posts
Colin Williams - 31 October 2008 08:37 AM

I do however care about having to do useless stuff, like loading a header and title in about every function, wehn solving that I ran into the issue this bug is about.

The Views system in CodeIgniter is THE way to present output to the client; THE way. So, when you decide to step out of this foundational convention, you are going to end up circumventing a lot of other things in CI. I have this feeling that you come up on these problems of logic and become frustrated that CI cannot solve your problem. The best experience with a framework can only be had if either your buy 100% in to its conventions, or you become familiar enough to know how to least destructively subvert the conventions, when it serves well to do so.

I don’t see the relation between my quoted post and your post… I’m using views, I’m actually even using a view for my template… Before multiple view support was introduced (I believe that was somewhere in the 1.6 series) the only possibility was to have multiple views loaded and concatenated with echo commands (echo $this->load->view(‘1’, ‘’, true); echo $this->load->view(‘2’, ‘’, true);).

The fact that the codeigniter folks build other engines on top of CI doesn’t mean they’ve thought about every possible combination of code execution. It still seems to me CodeIgniter is filling in the developer requirements, not necessarily the user requirements. That’s not an issue, but that would explain if they haven’t ever thought about buffering output that’s being echoed… Maybe the codeigniter/expressionengine devs have nested views, with a parent view for every function inside controllers. That would work perfectly fine (because you can echo in a view as much as you want), and would allow them to cache the end result.

If I wanted to I could solve my issue the exact same way, but I don’t want to… Because some people say the behaviour I’m describing in my bug report is expected behaviour, I’m just trying to figure out if that’s true (truly expected) or that the devs just have never bothered to ‘really’ buffer all content because noone ever needed it.

In reaction to the last part of your quoted post above: I’m not frustated with this codeigniter behaviour, I’m just wondering about the correctness of the behaviour. I have actually already solved the behaviour for my issues, by loading views directly instead of echoing.

These days I always use views when creating new code, at least when working towards an end result, and I would suggest the same thing to anyone developing new code. I can however understand anyone using echoes (or print_r for that matter) in the process of developing new code. I can even understand people echoeing stuff for final use, although that probably means they’re not efficiently using the MVC model. Do note however, that before multiple view support was available, echoing views was the only way to use multiple views from one controller function, and I think everyone will agree that to minimize code duplication you should sometimes split views into smaller parts.
Regards,

Michael

 
Posted: 31 October 2008 03:07 PM   [ # 15 ]   [ Rating: 0 ]
Avatar
Joined: 2006-07-27
2617 posts

Do note however, that before multiple view support was available, echoing views was the only way to use multiple views from one controller function

That’s just wrong.

$data = array(
   
'header' => $this->load->view('common/header', array(), TRUE),
   
'content' => $this->load->view('common/content', array(), TRUE),
   
'footer' => $this->load->view('common/footer', array(), TRUE),
);
$this->load->view('layout'$data);
// This is the premise behind my Template library 

And look, I get what you’re doing—you’re using this scenario to play Gotcha! with the CI dev team—I just don’t understand what ends you are trying to meet. EL is very clear about the direction they went with Views and output in CodeIgniter (as the docs show). Printing/echoing from a Controller is opposite that direction.

I’m just wondering about the correctness of the behaviour. I have actually already solved the behaviour for my issues

Well, no need to wonder anymore. It is the expected behaviour. The dev went the direction they did on purpose, not by accident or ignorance.

 Signature 

Check out the Template Library
Oh yeah, I tweet, too (regarding CodeIgniter on occassion).

 
1 of 2
1