The idea of the template engine comes from the MVC Model View Controller, which is the model layer, the view layer, and the controller layer.
On the web side, the model layer is the operation of the database; The view layer is the template, which is the Web front-end; Controller is the various operations of PHP on data and requests. The template engine is designed to separate the view layer from the other layers so that the PHP code and the HTML code are not mixed together. Because when the PHP code is mixed with the HTML code, it makes the code less readable and the maintenance of the code later becomes difficult.
Most of the template engine principle is similar, the core is to use the regular expression parsing template, the agreed to the specific identification statement compiled into a PHP statement, and then call only need to include compiled files, so that the PHP statement and HTML statements separated. You can even further output the output of PHP to the buffer, and then compile the template into a static HTML file, so the request is to open the static HTML file directly, the request speed greatly faster.
The simple custom template engine is two classes, the first is the template class, and the second is the compilation class.
The first is to compile the class:
Class Compileclass {
private $template; The file to be compiled
private $content; Text that needs to be replaced
private $compile _file; The compiled file
private $left = ' {'; Left delimiter
private $right = '} '; Right delimiter
private $include _file = Array (); The introduction of the file
private $config; Configuration file for templates
private $T _p = Array (); The expression that needs to be replaced is
private $T _r = Array (); The replaced string public
function __construct ($template, $compile _file, $config) {} public
function compile () {
$this->c_include ();
$this->c_var ();
$this->c_staticfile ();
File_put_contents ($this->compile_file, $this->content);
}
Processing include public
function C_include () {}
//handling various assignments and basic statement public
function C_var () {}
// Parse public
function C_staticfile () {}} for static JavaScript
The approximate structure of a compiled class is the above, and the work of compiling a class is based on a configured file that parses the written template file according to the rules, replaces it, and outputs it to the file. The content of this file is mixed with PHP and HTML, but you don't need to care about this file when you develop with the template engine, because we're going to write the template file, which is a file mixed with HTML and our own defined tags. So the view is separated from the other two layers.
In this custom template engine, my left and right delimiters are curly braces, and the specific parsing rule is in the __construct ()
The regular expression that needs to be replaced $this->t_p[] = "/$this->left\s*\\$ ([a-za-z_\x7f-\xff][a-za-z0-9_\xf7-\xff]*) \s* $this->right
/"; $this->t_p[] = "/$this->left\s* (Loop|foreach) \s*\\$ ([a-za-z_\x7f-\xff][a-za-z0-9_\xf7-\xff]*) \s* $this->
right/"; $this->t_p[] = "/$this->left\s* (Loop|foreach) \s*\\$ ([a-za-z_\x7f-\xff][a-za-z0-9_\xf7-\xff]*) \s+".
"As\s+\\$ ([a-za-z_\x7f-\xff][a-za-z0-9_\xf7-\xff]*) $this->right/";
$this->t_p[] = "/$this->left\s*\/(loop|foreach|if) \s* $this->right/"; $this->t_p[] = "/$this->left\s*if (. *?)
\s* $this->right/"; $this->t_p[] = "/$this->left\s* (Else If|elseif) (. *?)
\s* $this->right/";
$this->t_p[] = "/$this->left\s*else\s* $this->right/";
$this->t_p[] = "/$this->left\s* ([a-za-z_\x7f-\xff][a-za-z0-9_\xf7-\xff]*) \s* $this->right/";
The replaced string $this->t_r[] = "<?php echo \$\\1;?>"; $this->t_r[] = "<?php foreach (array) \$\\2 as \ $K =>\ $V) {?>"; $this->t_r[] = "<?php foreach (array) \$\ \2 as\$\\3) {?> "; $this->t_r[] =" <?php}?> "; $this->t_r[] = "<?php if (\\1) {?>"; $this->t_r[] = "<?php} elseif (\\2) {?>"; $this->t_r[] = "
php} else {?> "; $this->t_r[] =" <?php echo \$\\1;?> ";
The parsing rule above contains the basic output and some common syntax, if, foreach, and so on. The template file can be replaced with the Preg_replace function. The specific situation is as follows
<!--template file-->
{$data}
{foreach $vars}
{if $V = = 1}
<input value= ' {V} ' >
{elseif $V = = 2}< C6/><input value= "123123" >
{else}
<input value= "Sdfsas is AA" >
{/if}
{/foreach}
{ Loop $vars as $var}
<input value= "{var}" >
{/loop}
//parsed
<?php echo $data;?>
<?php foreach (array) $vars as $K => $V) {?>
<?php if ($V = = 1) {?> <input
value= "<?php Echo $V?> ">
<?php} elseif ($V = = 2) {?>
<input value= ' 123123 ' >
<?php} else {? >
<input value= "Sdfsas is AA" >
<?php}?>
<?php}?>
<?php foreach (array) $vars as & amp; $var) {?>
<input value= "<?php echo $var;?>" >
<?php}?>
The work of compiling classes is roughly the same, and the rest of the include and the parsing of JavaScript are similar to this.
And then there's the template class
Class Template {//Configuration $_arrayconfig = Array (' Root ' => ',//file root ' suffix ' => '. html ',//template text Suffix ' template_dir ' => ' templates ',//Templates folder ' Compile_dir ' => ' templates_c ',//post-compiled folder ' Cache_dir ' => ' Cache ',//static HTML store address ' cache_htm ' => false,//whether to compile the static HTML file ' Suffix_cache ' => '. htm ',//Set the suffix of the compiled file ' Cach
E_time ' => 7200,//Automatic update interval ' Php_turn ' => true,//whether support native PHP code ' debug ' => ' false ',);
Private $_value = Array (); Private $_compiletool;
compiler static Private $_instance = NULL; public $file; Template filename Public $debug = Array (); Debug information Public Function __construct ($array _config=array ()) {}//Single-step configuration file Public function Setconfig ($key, $value =nu ll) {}//inject a single variable public function assign ($key, $value) {}///inject array variable public function Assignarray ($array) {}//whether Turn on Cache public Function Needcache () {}//If you need to recompile file Public function recache () {}//Display template public function show ($file
) {}
}
The workflow for the entire template class is to instantiate the template class object first, and then use the Assign and Assignarray methods to assign values to the variables in the template, and then call the Show method, pass the templates and configuration files to the instantiated object of the compiled class, and then directly include the compiled PHP, HTML mixed file, showing output. The simple process is this, the detailed code is as follows
Public function Show ($file) {$this->file = $file;
if (!is_file ($this->path ()) {exit ("Cannot find the corresponding template file"); $compile _file = $this->_arrayconfig[' Compile_dir ']. MD5 ($file).
'. php '; $cache _file = $this->_arrayconfig[' Cache_dir ']. MD5 ($file).
$this->_arrayconfig[' Suffix_cache ']; If you need to recompile the file if ($this->recache ($file) = = False) {$this->_compiletool = new Compileclass ($this->path (), $com
Pile_file, $this->_arrayconfig);
if ($this->needcache ()) {//output to buffer Ob_start ();
///To import the assigned variable into the current symbol table extract ($this->_value, extr_overwrite); if (!is_file ($compile _file) or Filemtime ($compile _file) < Filemtime ($this->path ())) {$this->_compiletool-
>vars = $this->_value;
$this->_compiletool->compile ();
Include ($compile _file);
else {include ($compile _file);
//If you need to compile to a static file if ($this->needcache () = = True) {$message = Ob_get_contents ();
File_put_contents ($cache _file, $message); } else {ReadFile ($cache _file);
}
}
In the Show method, I first determine the existence of the template file and then use the MD5 encoding to generate the file name of the compiled file and the cached file. Then it is to determine whether the need to compile, the basis for the judgment is to see whether the compilation file exists and compile the file write time is less than the template file. If you need to compile, use the compile class to compile and generate a PHP file. Then you just need to include the compiled file.
To speed up the loading of the template, you can output the compiled file to the buffer, that is, Ob_start (), all output will not be output to the browser, but output to the default buffer, in the use of ob_get_contents () to read out the output, Saved as a static HTML file.
The specific use is as follows
Require (' template.php ');
$config = Array (
' Debug ' => true,
' cache_htm ' => false,
' debug ' => true
);
$TPL = new Template ($config);
$tpl->assign (' Data ', Microtime (true));
$tpl->assign (' VARs ', Array (1,2,3));
$tpl->assign (' title ', "HHhH");
$tpl->show (' Test ');
The cached files are as follows
A simple custom template engine is done, albeit rudimentary but can be used, and the focus is on making wheels fun and rewarding.
The full code shows my github.
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.