In this brief example i don't entry in the "model" (M) question (ie, how to manage data from database or what else). The purpose of this article is to know how manage PIECES of HTML (the "views" of the MVC) probably with dynamic php insertions in them.
The quit of the question is the CONTROL OF THE BUFFER. I don't pretend to offer here a tutorial about the php buffer, but let me remember the main concepts for the beginners:
- the php server, by default return to the client browser whatever you output with an echo command, for example, or whatever you include in your php files outside the tags.
- optionally, we can indicate to php for store these returned texts in a buffer and not to send to client browser until we need. In fact the system is more sophisticated and php give the developers a collection of functions for start, retrieve, clean or return this buffer. It sounds fine, it isn't?
view.php
1 <h1><?= $msg ?></h1>
index.php
1 <?php
2
3 $output1 = renderView('view.php','this is HEADER');
4
5 $output2 = renderView('view.php','this is FOOTER');
6
7 $output3 = renderView('view.php','this is MAIN CONTENT');
8
9 echo $output1.$output3.$output2;
10
11 function renderView($viewname,$msg){
12 ob_start( );
13 include($viewname);
14 $render = ob_get_clean( );
15 ob_end_clean();
16 return $render;
17 }
18
19 ?>
Browser output
1 <h1>this is HEADER</h1>
2 <h1>this is MAIN CONTENT</h1>
3 <h1>this is FOOTER</h1>
Analysis of this codes
- My first goal is to build the HTML of my web application in files like the view.php where the format is truly HTML&CSS and the minimal PHP code, and manage data in the "model" or the "controller" (index.php) files (in this sense, better in the model than in the controller... remember this: fat model thin controller).
- My second goal is to CONTROL WHEN TO SEND html to client browser (or webservice, or whatever other client), because in a real environment (not like here in this toy example) i would need to manipulate these different HTML pieces that the components of my application will generate (menus, widgets, etc.) before to join in a unique HTML raw stream for send to browser.
- for this reason, the view.php file is almost a piece of HTML&CSS code where i can INSERT pieces of php which will replace this kind of "placeholders" just like it was a template.
It's important to note here that the variables which will be accessible from view.php are uniquely the variables accessible within the function (or method) where we use the include() command. - Obviously, the most interesting part of this example is the function renderView($viewname,$msg):
- When we call ob_start() the Output Buffer begin to store all what we return as echo or what we include outside php tags (like the content of the view.php file).
- With ob_get_clean() we retrieve the content stored at this moment, and also empty the buffer.
- And finally, with ob_end_clean() we finish the buffering, although we can use it again afterward with ob_start(), as many times as we need.
As you see, is very simple then to build a mini MVC logic for your web applications. Think that this control of the buffer let us for example store the output in some kind of cache (in a folder of our application) before to send to browser, for example. Or we could store some "little dynamic" pieces of HTML in this cache, or we could REUSE the same generated HTML (some widget?) in different places of the same HTML page without to generate twice. Etcetera...
I hope this mini-guide has given to you some good ideas. Please, add comments and suggestions if you have.
Update 16/07/2014
The initial renderView() function don't let to recursively include a view render inside another view render. For solve this need i improved the function just as you read below:
1 <?php
2 function renderView($viewname,Array $vars){
3 // == we convert the variables passed in vars
4 // == to "real" native PHP variables
5 if (count($vars)>0){
6 foreach($vars as $k=>$v){
7 ${$k}=$v;
8 }
9 }
10 // == we save a copy of the content already existing
11 // == at the output buffer (for no interrump it)
12 $existing_render = ob_get_clean( );
13 // == we begin a new output
14 ob_start( );
15 include(dirname(__FILE__).'/view_'.$viewname.'.php');
16 // == we get the current output
17 $render = ob_get_clean( );
18 // == we re-send to output buffer the existing content
19 // == before to arrive to this function ;)
20 ob_start( );
21 echo $existing_render;
22
23 return $render;
24 }
25 ?>
- $html = renderView('main_content', array('age'=>44));
- Age: <?= $age ?> years old.