PHP template parsing class
-
-
- Class template {
- Private $ vars = array ();
- Private $ conf = '';
- Private $ tpl_name = 'index'; // if the template does not exist, the default index template of the current controller will be searched.
- Private $ tpl_suffix = '.html '; // it is displayed if the default suffix is not configured in CONFIG.
- Private $ tpl_compile_suffix = '. tpl. php'; // compile the template path.
- Private $ template_tag_left = '<{'; // left tag of the template
- Private $ template_tag_right = '}>'; // right tag of the template
- Private $ template_c = ''; // compiled Directory
- Private $ template_path = ''; // Complete template path
- Private $ template_name = ''; // template name index.html
-
-
- // Define the tag elements of each template
- Private $ tag_foreach = array ('from', 'item', 'key ');
- Private $ tag_include = array ('file'); // currently, only the default template path can be read.
-
- Public function _ construct ($ conf ){
- $ This-> conf = & $ conf;
-
- $ This-> template_c = $ this-> conf ['Template _ config'] ['Template _ c']; // compile the 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
- * @ Return array
- */
-
- Private function preg_match_all ($ pattern, $ content ){
- If (empty ($ pattern) | empty ($ content) core: show_error ('Template tag search 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;
- }
-
- /**
- * This is not explained here.
- * @ Return
- */
- Public function assign ($ key, $ value ){
- $ This-> vars [$ key] = $ value;
- }
-
- /**
- * Rendering page
- * @ Param
- * Method 1
- * $ This-> view-> display ('error', 'comm /');
- * By default, it is directed to the following Directory of the TPL template. Therefore, comm/is tpl/comm/error.html.
- * Method 2
- * $ This-> view-> display ('errorfile ');
- * By default, it points to a fixed folder of the controller.
- * For example, if your domain name is http: // heartphp/admin/index, 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); // obtain the full path of TPL and transmit the path and name to the pointer.
- If (! $ Tpl_path_arr) core: show_error ($ filename. $ this-> _ tpl_suffix. 'template does not exist ');
-
- // Start compilation
- $ This-> view_path_param = $ view_path; // template and directory passed by the user
- $ This-> compile ();
-
- }
-
- /**
- * Compile the 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); // Parse
- 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 configuration file of the current project.
- */
- Protected function read_config (){
- If (file_exists (SYSTEM_PATH. 'conf/config. php ')){
- @ Include SYSTEM_PATH. 'conf/config. php ';
- Return $ config;
- }
-
- Return false;
- }
- /**
- * Parse template syntax
- * @ Param $ str content
- * @ Param $ compile_dirpath template compilation Directory
- * @ Param $ vars_template_c_name: template compilation 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 ('The template content is blank! ');
-
- // Process the compilation header
- $ Compile_path = $ compile_dirpath. $ vars_template_c_name. $ this-> tpl_compile_suffix; // compile the file
-
- 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 has expired, compile it again when the template tag has include and is modified.
- // <{Include file = "public/left.html"}> when modifying the file in include, if the file does not change the main file in non-DEBUG mode, the file in include is not re-compiled, i'm thinking about whether to change it as well. I don't think about it for the time being. so in the development stage, we must enable the DEBUG = 1 mode. Otherwise, it will be invalid to modify the include file. Not clear.
- If ($ tpl_filemtime> $ compile_filemtime | DEBUG ){
- $ Ret_file = $ this-> compile_file ($ vars_template_c_name, $ str, $ compile_dirpath );
- } Else {
- $ Ret_file = $ compile_path;
- }
- } Else {// The compilation file does not exist.
- $ Ret_file = $ this-> compile_file ($ vars_template_c_name, $ str, $ compile_dirpath );
- }
-
- Return $ ret_file;
- }
-
-
- /**
- * Template File subject
- * @ Param string $ str content
- * @ Return html
- */
- Private function body_content ($ str ){
- // Resolution
- $ 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 tag public part
- $ Content = $ this-> parse_comm ($ content );
-
- // Convert to php code
- $ Content = $ this-> parse_php ($ content );
- Return $ content;
- }
-
- /**
- * Echo: convert <{$ config ['domain ']}>
- */
- Private function parse_echo ($ content ){
-
- }
-
- /**
- * Convert to PHP
- * @ Param $ content html template content
- * @ Return html: replaced 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 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 tag is not updated in real time. the tag content is updated only when the subject file is updated. to make the include effective, modify the subject file.
- * Record the time to develop a template compilation file that is deleted each time in DEBUG mode.
- * Usage <{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 element
- 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 ('The template path does not exist! ');
- }
- }
- }
-
- Extract ($ new_tag );
- // Query the 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); // Parse
-
- Break;
- } Else {
- Core: show_error ('Template file does not exist. check the file carefully: '. $ conf_view_tpl );
- }
- }
-
- $ Content = str_replace ($ match [0] [$ match_key],' ', $ Content );
- }
-
- Return $ content;
-
- }
- /**
- * Parse foreach
- * Usage <{foreach from = $ lists item = value key = kk}>
- * @ Param $ content template content
- * @ Return html parsed content
- */
- 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) {// filter tags that do not exist here
- $ 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 the 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 the compilation Directory. If no directory is created, recursively create the directory.
- * @ Param string $ path: complete file 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 files
- * @ Param string $ path: complete file path
- * @ Return template content
- */
- Private function read_file ($ path ){
- // $ This-> check_file_limits ($ path, 'r ');
-
- If ($ r = @ fopen ($ path, 'r') === false ){
- Core: show_error ('The template file has no read or execution permissions. Please check it! ');
- }
- $ Content = fread ($ r, filesize ($ path ));
- Fclose ($ r );
- Return $ content;
- }
-
- /**
- * Write a file
- * @ 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); // operations on the file content
- // Echo 'starts to compile ==== ';
- $ 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 the file. check the file permission .');
- }
- // Enable flock
- Flock ($ fp, LOCK_EX + LOCK_NB );
- Fwrite ($ fp, $ content, strlen ($ content ));
- Flock ($ fp, LOCK_UN + LOCK_NB );
- Fclose ($ fp );
-
- Return $ f;
- }
-
- /**
- * This file permission function is temporarily obsolete.
- * @ 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 it into an array.
- * @ Param string $ filepath file path
- * @ Param number $ line number of rows
- * @ Return returns the string of 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 permission! ');
- }
- Return $ file_arr [0];
- }
- */
-
- /**
- * Date on which the header comment is analyzed
- * @ Param string $ the first line in the header of the cotnent compilation file
- * @ Return returns the last date
- */
- /*
- Private function get_compile_header_comment ($ content ){
- Preg_match ("/\/\*(.*?) \ * \ // ", $ Content, $ match );
- If (! Isset ($ match [1]) | empty ($ match [1]) core: show_error ('Compilation error! ');
- $ Arr = explode ('|', $ match [1]);
- $ Arr_date = explode ('#', $ arr [0]);
-
- Return $ arr_date [1];
- }
- */
- /**
- * Obtain the complete template path and return an 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 the template path
- Foreach ($ this-> conf ['view _ path'] as $ path ){
- If ($ view_path) {// find the file directly from the tpl and Directory
- $ Tpl_path = $ path. $ view_path;
- $ View_file_path = $ tpl_path. $ filename. $ this-> _ tpl_suffix;
- } Else {// locate the file according to the Directory, controller, and method
- $ 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 the template path and template name to the 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 ');
- }
- }
- }
-
- /**
- * Obtain the template path
- * @ Param string $ path main directory
- * @ Return url d and M splicing paths
- */
- 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 ('an error occurred while obtaining the template path! ');
-
- 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 whether you have the write permission! ');
- }
- Chmod ($ allpath, $ mode );
- } Else {
- $ Newdir = $ allpath;
- }
- }
- Return true;
- }
-
- Public function _ destruct (){
- $ This-> vars = null;
- $ This-> view_path_param = null;
- }
-
- };
|