PHP Template Parsing class
-
- Class Template {
- Private $vars = Array ();
- Private $conf = ';
- Private $TPL _name = ' index ';//If the template does not exist, it will find the current Controller default index template
- Private $tpl _suffix = '. html ';//if config is not configured with a default suffix display
- Private $tpl _compile_suffix= '. tpl.php ';//compile template path
- Private $template _tag_left = ' <{';//template left label
- Private $template _tag_right = '}> ';//Template Right Tag
- Private $template _c = ";//Compile Directory
- Private $template _path = ";//Template full path
- Private $template _name = ";//Template name index.html
- The element that defines the label for each template
- Private $tag _foreach = Array (' From ', ' item ', ' key ');
- Private $tag _include = Array (' file ');//Currently only read template default path is supported
- Public function __construct ($conf) {
- $this->conf = & $conf;
- $this->template_c = $this->conf[' template_config ' [' Template_c '];//compile directory
- $this->_tpl_suffix = $this->tpl_suffix ();
- }
- Private Function Str_replace ($search, $replace, $content) {
- if (Empty ($search) | | empty ($replace) | | empty ($content)) return false;
- Return Str_replace ($search, $replace, $content);
- }
- /**
- * Preg_match_all
- * @param $pattern Regular
- * @param $content Content
- * @return Array
- */
- Private Function Preg_match_all ($pattern, $content) {
- if (Empty ($pattern) | | empty ($content)) Core::show_error (' Find template tag failed! ');
- Preg_match_all ("/". $this->template_tag_left. $pattern. $this->template_tag_right. " /is ", $content, $match);
- return $match;
- }
- /**
- * Template file suffix
- */
- Public Function Tpl_suffix () {
- $tpl _suffix = Empty ($this->conf[' template_config ' [' Template_suffix '])?
- $this->tpl_suffix:
- $this->conf[' template_config ' [' Template_suffix '];
- return $TPL _suffix;
- }
- /**
- * not explained here.
- * @return
- */
- Public function assign ($key, $value) {
- $this->vars[$key] = $value;
- }
- /**
- * Render Page
- * @param
- * How to use 1
- * $this->view->display (' Error ', ' comm/');
- * The default is to refer to the TPL template with the directory, so comm/is tpl/comm/error.html
- * How to use 2
- * $this->view->display (' ErrorFile ');
- * Default point to Controller pinned folder
- * For example your domain name is http://heartphp/admin/index, then the correct path is tpl/admin/index/errorfile.html
- * @return
- */
- Public function display ($filename = ', $view _path = ') {
- $tpl _path_arr = $this->get_tpl ($filename, $view _path);//Get the TPL full path and route the path and name to the pointer
- if (! $tpl _path_arr) Core::show_error ($filename. $this->_tpl_suffix. ' Template does not exist ');
- Compile start
- $this->view_path_param = $view templates and directories passed by _path;//users.
- $this->compile ();
- }
- /**
- * Compiler Controller
- * @param
- * @return
- */
- Private function compile () {
- $filepath = $this->template_path. $this->template_name;
- $compile _dirpath = $this->check_temp_compile ();
- $vars _template_c_name = Str_replace ($this->_tpl_suffix, ", $this->template_name);
- $include _file = $this->template_replace ($this->read_file ($filepath), $compile _dirpath, $vars _template_c_name );//parsing
- if ($include _file) {
- $this->read_config () && $config = $this->read_config ();
- Extract ($this->vars, Extr_skip);
- [url=home.php?mod=space&uid=48608] @include [/url] $include _file;
- }
- }
- /**
- * Read the current project configuration file
- */
- protected function Read_config () {
- if (file_exists (system_path. ' conf/config.php ')) {
- @include system_path. ' conf/config.php ';
- return $config;
- }
- return false;
- }
- /**
- * Parsing template syntax
- * @param $str Content
- * @param $compile _dirpath Template Compilation Directory
- * @param $vars _template_c_name template Compile file name
- * @return compiled php template file name
- */
- Private Function Template_replace ($str, $compile _dirpath, $vars _template_c_name) {
- if (empty ($STR)) core::show_error (' template content is empty! ');
- Handling the compilation header
- $compile _path = $compile _dirpath. $vars _template_c_name. $this->tpl_compile_suffix;//Compiling files
- if (Is_file ($compile _path)) {
- $header _content = $this->get_compile_header ($compile _path);
- $compile _date = $this->get_compile_header_comment ($header _content);
- $tpl _filemtime = Filemtime ($this->template_path. $this->template_name);
- $compile _filemtime = filemtime ($compile _path);
- echo $tpl _filemtime. ' = = '. Date (' y-m-d h:i:s ', $tpl _filemtime). '
';
- echo $compile _filemtime. ' = = '. Date (' y-m-d h:i:s ', $compile _filemtime);
- If the file expires compiling when the template tag has an include and is modified also recompile
- <{include file= "public/left.html"}> when modifying the file in the include, non-debug mode if not change the main file is currently not recompiled the file in the include, I am considering whether to change, do not think well, For the time being, so be sure to turn on the debug=1 mode in the development phase or modify the include file to be invalid. A little wordy, I do not know the statement clearly
- if ($tpl _filemtime > $compile _filemtime | | DEBUG) {
- $ret _file = $this->compile_file ($vars _template_c_name, $str, $compile _dirpath);
- } else {
- $ret _file = $compile _path;
- }
- } else {//compile file does not exist create his
- $ret _file = $this->compile_file ($vars _template_c_name, $str, $compile _dirpath);
- }
- return $ret _file;
- }
- /**
- * Template file Body
- * @param string $str content
- * @return HTML
- */
- Private Function Body_content ($STR) {
- Analytical
- $str = $this->parse ($STR);
- $header _comment = "Create on##". Time (). "| Compiled from## ". $this->template_path. $this->template_name;
- $content = " \r\n$str";
- return $content;
- }
- /**
- * Start parsing related template tags
- * @param $content Template content
- */
- Private Function Parse ($content) {
- Foreach
- $content = $this->parse_foreach ($content);
- Include
- $content = $this->parse_include ($content);
- If
- $content = $this->parse_if ($content);
- ElseIf
- $content = $this->parse_elseif ($content);
- Template label Common section
- $content = $this->parse_comm ($content);
- Switch to PHP code
- $content = $this->parse_php ($content);
- return $content;
- }
- /**
- * echo If the default direct <{$config [' domain ']}> turns into
- */
- Private Function Parse_echo ($content) {
- }
- /**
- * Convert to PHP
- * @param $content HTML template content
- * @return HTML to replace good HTML
- */
- Private Function parse_php ($content) {
- if (empty ($content)) return false;
- $content = Preg_replace ("/". $this->template_tag_left. " (.+?)". $this->template_tag_right. " /is "," " , $content);
- return $content;
- }
- /**
- * If Judgment statement
- * <{if Empty ($zhang)}>
- * Zhang
- * <{elseif Empty ($liang)}>
- * Liang
- * <{else}>
- * Zhangliang
- * <{/if}>
- */
- Private Function parse_if ($content) {
- if (empty ($content)) return false;
- Preg_match_all ("/". $this->template_tag_left. " If\s+ (. *?) ". $this->template_tag_right. " /is ", $content, $match);
- $match = $this->preg_match_all ("if\s+ (. *)", $content);
- if (!isset ($match [1]) | |!is_array ($match [1])) return $content;
- foreach ($match [1] as $k = + $v) {
- $s = Preg_split ("/\s+/is", $v);
- $s = array_filter ($s);
- $content = Str_replace ($match [0][$k], " ", $content);
- }
- return $content;
- }
- Private Function Parse_elseif ($content) {
- if (empty ($content)) return false;
- Preg_match_all ("/". $this->template_tag_left. " Elseif\s+ (. *?) ". $this->template_tag_right. " /is ", $content, $match);
- $match = $this->preg_match_all ("elseif\s+ (. *)", $content);
- if (!isset ($match [1]) | |!is_array ($match [1])) return $content;
- foreach ($match [1] as $k = + $v) {
- $s = Preg_split ("/\s+/is", $v);
- $s = array_filter ($s);
- $content = Str_replace ($match [0][$k], " ", $content);
- }
- return $content;
- }
- /**
- * Parsing the include include tag is not updated in real time when the main file updates the label content, so want to include the effective please modify the main file
- * Record a time to develop a debug mode when you execute a delete template compile file
- * How to use <{include file= "www.phpddt.com"}>
- * @param $content Template content
- * @return HTML
- */
- Private Function Parse_include ($content) {
- if (empty ($content)) return false;
- Preg_match_all ("/". $this->template_tag_left. " Include\s+ (. *?) ". $this->template_tag_right. " /is ", $content, $match);
- $match = $this->preg_match_all ("include\s+ (. *)", $content);
- if (!isset ($match [1]) | |!is_array ($match [1])) return $content;
- foreach ($match [1] as $match _key = $match _value) {
- $a = Preg_split ("/\s+/is", $match _value);
- $new _tag = Array ();
- Analysis elements
- foreach ($a as $t) {
- $b = explode (' = ', $t);
- if (In_array ($b [0], $this->tag_include)) {
- if (!empty ($b [1])) {
- $new _tag[$b [0]] = str_replace ("\" "," ", $b [1]);
- } else {
- Core::show_error (' template path does not exist! ');
- }
- }
- }
- Extract ($new _tag);
- Query template file
- foreach ($this->conf[' View_path ') as $v) {
- $conf _view_tpl = $v. $file;//include template file
- if (Is_file ($conf _view_tpl)) {
- $c = $this->read_file ($conf _view_tpl);
- $inc _file = Str_replace ($this->_tpl_suffix, ", basename ($file));
- $this->view_path_param = dirname ($file). ' /';
- $compile _dirpath = $this->check_temp_compile ();
- $include _file = $this->template_replace ($c, $compile _dirpath, $inc _file);//parsing
- Break
- } else {
- Core::show_error (' template file does not exist, please double check the file: '. $conf _view_tpl);
- }
- }
- $content = Str_replace ($match [0][$match _key], " , $content);
- }
- return $content;
- }
- /**
- * Parsing foreach
- * How to use <{foreach from= $lists item=value key=kk}>
- * @param $content Template content
- * @return The content after parsing HTML
- */
- Private Function Parse_foreach ($content) {
- if (empty ($content)) return false;
- Preg_match_all ("/". $this->template_tag_left. " Foreach\s+ (. *?) ". $this->template_tag_right. " /is ", $content, $match);
- $match = $this->preg_match_all ("foreach\s+ (. *)", $content);
- if (!isset ($match [1]) | |!is_array ($match [1])) return $content;
- foreach ($match [1] as $match _key = $value) {
- $split = Preg_split ("/\s+/is", $value);
- $split = Array_filter ($split);
- $new _tag = Array ();
- foreach ($split as $v) {
- $a = explode ("=", $v);
- if (In_array ($a [0], $this->tag_foreach)) {//Here Filter label does not exist filter
- $new _tag[$a [0]] = $a [1];
- }
- }
- $key = ";
- Extract ($new _tag);
- $key = ($key)? ' $ '. $key. ' = ': ';
- $s = " ;
- $content = $this->str_replace ($match [0][$match _key], $s, $content);
- }
- return $content;
- }
- /**
- * Match End string
- */
- Private Function Parse_comm ($content) {
- $search = Array (
- "/". $this->template_tag_left. " \/foreach ". $this->template_tag_right." /is ",
- "/". $this->template_tag_left. " \/if ". $this->template_tag_right." /is ",
- "/". $this->template_tag_left. " Else ". $this->template_tag_right." /is ",
- );
- $replace = Array (
- " ",
- " ",
- " "
- );
- $content = Preg_replace ($search, $replace, $content);
- return $content;
- }
- /**
- * Check compilation directory if not created, recursively create directory
- * @param string $path file full path
- * @return Template content
- */
- Private Function Check_temp_compile () {
- $paht = $this->template_c.
- $tpl _path = ($this->view_path_param)? $this->view_path_param: $this->get_tpl_path ();
- $all _tpl_apth = $this->template_c. $TPL _path;
- if (!is_dir ($all _tpl_apth)) {
- $this->create_dir ($tpl _path);
- }
- return $all _tpl_apth;
- }
- /**
- * Read File
- * @param string $path file full path
- * @return Template content
- */
- Private Function Read_file ($path) {
- $this->check_file_limits ($path, ' R ');
- if ($r = @fopen ($path, ' r ') = = = = False) {
- Core::show_error (' template file does not have read or EXECUTE permission, please check! ');
- }
- $content = Fread ($r, FileSize ($path));
- Fclose ($R);
- return $content;
- }
- /**
- * Write files
- * @param string $filename file name
- * @param string $content template content
- * @return File name
- */
- Private Function Compile_file ($filename, $content, $dir) {
- if (empty ($filename)) Core::show_error ("{$filename} Creation failed");
- $content = $this->body_content ($content);//operation on file contents
- Echo ' started compiling the ===== ';
- $f = $dir. $filename. $this->tpl_compile_suffix;
- $this->check_file_limits ($f, ' w ');
- if ($fp = @fopen ($f, ' wb ') = = = = False) {
- Core::show_error ($f. '
Failed to compile file, please check file permissions. ');
- }
- Open flock
- Flock ($fp, LOCK_EX + lock_nb);
- Fwrite ($fp, $content, strlen ($content));
- Flock ($fp, Lock_un + lock_nb);
- Fclose ($FP);
- return $f;
- }
- /**
- * This check file permission function is temporarily discarded.
- * @param [$path] [path]
- * @param [status] [W=write, R=read]
- */
- Public Function Check_file_limits ($path, $status = ' rw ') {
- Clearstatcache ();
- if (!is_writable ($path) && $status = = ' W ') {
- Core::show_error ("{$path}
No write permission, please check. ");
- } elseif (!is_readable ($path) && $status = = ' R ') {
- Core::show_error ("{$path}
No Read permission, please check. ");
- } elseif ($status = = ' rw ') {//check wirte and read
- if (!is_writable ($path) | |!is_readable ($path)) {
- Core::show_error ("{$path}
No write or Read permission, please check ");
- }
- }
- }
- /**
- * Read the first line of the compiled template and analyze the array
- * @param string $filepath file path
- * Number $line rows @param
- * @return A string that returns the specified number of rows
- */
- /*
- Private Function Get_compile_header ($filepath, $line = 0) {
- if ($file _arr = @file ($filepath)) = = = = False) {
- Core::show_error ($filepath. '
Failed to read file, please check file permissions! ');
- }
- return $file _arr[0];
- }
- */
- /**
- * Analyze the date of the header comment
- * @param string $cotnent Compile the first line of the file header
- * @return return Last Date
- */
- /*
- Private Function Get_compile_header_comment ($content) {
- Preg_match ("/\/\* (. *?) \*\//", $content, $match);
- if (!isset ($match [1]) | | empty ($match [1])) core::show_error (' Compile error! ');
- $arr = Explode (' | ', $match [1]);
- $arr _date = Explode (' # # ', $arr [0]);
- return $arr _date[1];
- }
- */
- /**
- * Get template full path and return existing file
- * @param string $filename file name
- * @param string $view _path template path
- * @return
- */
- Private Function Get_tpl ($filename, $view _path) {
- Empty ($filename) && $filename = $this->tpl_name;
- Traverse template Path
- foreach ($this->conf[' View_path ') as $path) {
- if ($view _path) {//Find files directly from the TPL and directory
- $tpl _path = $path. $view _path;
- $view _file_path = $tpl _path. $filename. $this->_tpl_suffix;
- } else {//based on directory, controller, method start looking for file
- $view _file_path = ($tpl _path = $this->get_tpl_path ($path))? $tpl _path. $filename. $this->_tpl_suffix:exit (0);
- }
- if (Is_file ($view _file_path)) {
- Transfer template path and template name to pointer
- $this->template_path = $tpl _path;//
- $this->template_name = $filename. $this->_tpl_suffix;
- return true;
- } else {
- Core::show_error ($filename. $this->_tpl_suffix. ' Template does not exist ');
- }
- }
- }
- /**
- * Get template path
- * @param string $path home directory
- * @return The stitching path of the URL D and M
- */
- Private Function Get_tpl_path ($path = ") {
- Core::get_directory_name () && $path _arr[0] = Core::get_directory_name ();
- Core::get_controller_name () && $path _arr[1] = Core::get_controller_name ();
- (Is_array ($path _arr))? $newpath = implode ('/', $path _arr): Core::show_error (' Get template path failed! ');
- Return $path. $newpath. ' /';
- }
- /**
- * Create a directory
- * @param string $path directory
- * @return
- */
- Private Function Create_dir ($path, $mode = 0777) {
- if (Is_dir ($path)) return false;
- $dir _arr = explode ('/', $path);
- $dir _arr = Array_filter ($dir _arr);
- $allpath = ";
- $newdir = $this->template_c;
- foreach ($dir _arr as $dir) {
- $allpath = $newdir. ' /'. $dir;
- if (!is_dir ($allpath)) {
- $newdir = $allpath;
- if (! @mkdir ($allpath, $mode)) {
- Core::show_error ($allpath. '
Failed to create directory, please check if you have Write permission! ');
- }
- chmod ($allpath, $mode);
- } else {
- $newdir = $allpath;
- }
- }
- return true;
- }
- Public Function __destruct () {
- $this->vars = null;
- $this->view_path_param = null;
- }
- };
Copy Code |