PHP template parsing class

Source: Internet
Author: User
Tags flock php foreach php template
PHP template parsing class
PHP template parsing class

  1. Class template {
  2. Private $ vars = array ();
  3. Private $ conf = '';
  4. Private $ tpl_name = 'index'; // if the template does not exist, the default index template of the current controller will be searched.
  5. Private $ tpl_suffix = '.html '; // it is displayed if the default suffix is not configured in CONFIG.
  6. Private $ tpl_compile_suffix = '. tpl. php'; // compile the template path.
  7. Private $ template_tag_left = '<{'; // left tag of the template
  8. Private $ template_tag_right = '}>'; // right tag of the template
  9. Private $ template_c = ''; // compiled Directory
  10. Private $ template_path = ''; // Complete template path
  11. Private $ template_name = ''; // template name index.html
  12. // Define the tag elements of each template
  13. Private $ tag_foreach = array ('from', 'item', 'key ');
  14. Private $ tag_include = array ('file'); // currently, only the default template path can be read.
  15. Public function _ construct ($ conf ){
  16. $ This-> conf = & $ conf;
  17. $ This-> template_c = $ this-> conf ['Template _ config'] ['Template _ c']; // compile the Directory
  18. $ This-> _ tpl_suffix = $ this-> tpl_suffix ();
  19. }
  20. Private function str_replace ($ search, $ replace, $ content ){
  21. If (empty ($ search) | empty ($ replace) | empty ($ content) return false;
  22. Return str_replace ($ search, $ replace, $ content );
  23. }
  24. /**
  25. * Preg_match_all
  26. * @ Param $ pattern regular
  27. * @ Param $ content
  28. * @ Return array
  29. */
  30. Private function preg_match_all ($ pattern, $ content ){
  31. If (empty ($ pattern) | empty ($ content) core: show_error ('Template tag search failed! ');
  32. Preg_match_all ("/". $ this-> template_tag_left. $ pattern. $ this-> template_tag_right. "/is", $ content, $ match );
  33. Return $ match;
  34. }
  35. /**
  36. * Template file suffix
  37. */
  38. Public function tpl_suffix (){
  39. $ Tpl_suffix = empty ($ this-> conf ['Template _ config'] ['Template _ suffix '])?
  40. $ This-> tpl_suffix:
  41. $ This-> conf ['Template _ config'] ['Template _ suffix '];
  42. Return $ tpl_suffix;
  43. }
  44. /**
  45. * This is not explained here.
  46. * @ Return
  47. */
  48. Public function assign ($ key, $ value ){
  49. $ This-> vars [$ key] = $ value;
  50. }
  51. /**
  52. * Rendering page
  53. * @ Param
  54. * Method 1
  55. * $ This-> view-> display ('error', 'comm /');
  56. * By default, it is directed to the following Directory of the TPL template. Therefore, comm/is tpl/comm/error.html.
  57. * Method 2
  58. * $ This-> view-> display ('errorfile ');
  59. * By default, it points to a fixed folder of the controller.
  60. * For example, if your domain name is http: // heartphp/admin/index, the correct path is tpl/admin/index/errorfile.html.
  61. * @ Return
  62. */
  63. Public function display ($ filename = '', $ view_path = ''){
  64. $ Tpl_path_arr = $ this-> get_tpl ($ filename, $ view_path); // obtain the full path of TPL and transmit the path and name to the pointer.
  65. If (! $ Tpl_path_arr) core: show_error ($ filename. $ this-> _ tpl_suffix. 'template does not exist ');
  66. // Start compilation
  67. $ This-> view_path_param = $ view_path; // template and directory passed by the user
  68. $ This-> compile ();
  69. }
  70. /**
  71. * Compile the controller
  72. * @ Param
  73. * @ Return
  74. */
  75. Private function compile (){
  76. $ Filepath = $ this-> template_path. $ this-> template_name;
  77. $ Compile_dirpath = $ this-> check_temp_compile ();
  78. $ Vars_template_c_name = str_replace ($ this-> _ tpl_suffix, '', $ this-> template_name );
  79. $ Include_file = $ this-> template_replace ($ this-> read_file ($ filepath), $ compile_dirpath, $ vars_template_c_name); // Parse
  80. If ($ include_file ){
  81. $ This-> read_config () & $ config = $ this-> read_config ();
  82. Extract ($ this-> vars, EXTR_SKIP );
  83. [Url = home. php? Mod = space & uid = 48608] @ include [/url] $ include_file;
  84. }
  85. }
  86. /**
  87. * Read the configuration file of the current project.
  88. */
  89. Protected function read_config (){
  90. If (file_exists (SYSTEM_PATH. 'conf/config. php ')){
  91. @ Include SYSTEM_PATH. 'conf/config. php ';
  92. Return $ config;
  93. }
  94. Return false;
  95. }
  96. /**
  97. * Parse template syntax
  98. * @ Param $ str content
  99. * @ Param $ compile_dirpath template compilation Directory
  100. * @ Param $ vars_template_c_name: template compilation file name
  101. * @ Return compiled PHP template file name
  102. */
  103. Private function template_replace ($ str, $ compile_dirpath, $ vars_template_c_name ){
  104. If (empty ($ str) core: show_error ('The template content is blank! ');
  105. // Process the compilation header
  106. $ Compile_path = $ compile_dirpath. $ vars_template_c_name. $ this-> tpl_compile_suffix; // compile the file
  107. If (is_file ($ compile_path )){
  108. // $ Header_content = $ this-> get_compile_header ($ compile_path );
  109. // $ Compile_date = $ this-> get_compile_header_comment ($ header_content );
  110. $ Tpl_filemtime = filemtime ($ this-> template_path. $ this-> template_name );
  111. $ Compile_filemtime = filemtime ($ compile_path );
  112. // Echo $ tpl_filemtime. '='. date ('Y-m-d H: I: S', $ tpl_filemtime ).'
    ';
  113. // Echo $ compile_filemtime. '='. date ('Y-m-d H: I: S', $ compile_filemtime );
  114. // If the file has expired, compile it again when the template tag has include and is modified.
  115. // <{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.
  116. If ($ tpl_filemtime> $ compile_filemtime | DEBUG ){
  117. $ Ret_file = $ this-> compile_file ($ vars_template_c_name, $ str, $ compile_dirpath );
  118. } Else {
  119. $ Ret_file = $ compile_path;
  120. }
  121. } Else {// The compilation file does not exist.
  122. $ Ret_file = $ this-> compile_file ($ vars_template_c_name, $ str, $ compile_dirpath );
  123. }
  124. Return $ ret_file;
  125. }
  126. /**
  127. * Template File subject
  128. * @ Param string $ str content
  129. * @ Return html
  130. */
  131. Private function body_content ($ str ){
  132. // Resolution
  133. $ Str = $ this-> parse ($ str );
  134. $ Header_comment = "Create On #". time (). "| Compiled from #". $ this-> template_path. $ this-> template_name;
  135. $ Content =" \ R \ n $ str ";
  136. Return $ content;
  137. }
  138. /**
  139. * Start parsing related template tags
  140. * @ Param $ content template content
  141. */
  142. Private function parse ($ content ){
  143. // Foreach
  144. $ Content = $ this-> parse_foreach ($ content );
  145. // Include
  146. $ Content = $ this-> parse_include ($ content );
  147. // If
  148. $ Content = $ this-> parse_if ($ content );
  149. // Elseif
  150. $ Content = $ this-> parse_elseif ($ content );
  151. // Template tag public part
  152. $ Content = $ this-> parse_comm ($ content );
  153. // Convert to php code
  154. $ Content = $ this-> parse_php ($ content );
  155. Return $ content;
  156. }
  157. /**
  158. * Echo: convert <{$ config ['domain ']}>
  159. */
  160. Private function parse_echo ($ content ){
  161. }
  162. /**
  163. * Convert to PHP
  164. * @ Param $ content html template content
  165. * @ Return html: replaced HTML
  166. */
  167. Private function parse_php ($ content ){
  168. If (empty ($ content) return false;
  169. $ Content = preg_replace ("/". $ this-> template_tag_left. "(. + ?) ". $ This-> template_tag_right."/is "," ", $ Content );
  170. Return $ content;
  171. }
  172. /**
  173. * If statement
  174. * <{If empty ($ zhang)}>
  175. * Zhang
  176. * <{Elseif empty ($ liang)}>
  177. * Liang
  178. * <{Else}>
  179. * Zhangliang
  180. * <{/If}>
  181. */
  182. Private function parse_if ($ content ){
  183. If (empty ($ content) return false;
  184. // Preg_match_all ("/". $ this-> template_tag_left. "if \ s + (.*?) ". $ This-> template_tag_right."/is ", $ content, $ match );
  185. $ Match = $ this-> preg_match_all ("if \ s + (.*?) ", $ Content );
  186. If (! Isset ($ match [1]) |! Is_array ($ match [1]) return $ content;
  187. Foreach ($ match [1] as $ k => $ v ){
  188. // $ S = preg_split ("/\ s +/is", $ v );
  189. // $ S = array_filter ($ s );
  190. $ Content = str_replace ($ match [0] [$ k]," ", $ Content );
  191. }
  192. Return $ content;
  193. }
  194. Private function parse_elseif ($ content ){
  195. If (empty ($ content) return false;
  196. // Preg_match_all ("/". $ this-> template_tag_left. "elseif \ s + (.*?) ". $ This-> template_tag_right."/is ", $ content, $ match );
  197. $ Match = $ this-> preg_match_all ("elseif \ s + (.*?) ", $ Content );
  198. If (! Isset ($ match [1]) |! Is_array ($ match [1]) return $ content;
  199. Foreach ($ match [1] as $ k => $ v ){
  200. // $ S = preg_split ("/\ s +/is", $ v );
  201. // $ S = array_filter ($ s );
  202. $ Content = str_replace ($ match [0] [$ k]," ", $ Content );
  203. }
  204. Return $ content;
  205. }
  206. /**
  207. * 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.
  208. * Record the time to develop a template compilation file that is deleted each time in DEBUG mode.
  209. * Usage <{include file = "www.phpddt.com"}>
  210. * @ Param $ content template content
  211. * @ Return html
  212. */
  213. Private function parse_include ($ content ){
  214. If (empty ($ content) return false;
  215. // Preg_match_all ("/". $ this-> template_tag_left. "include \ s + (.*?) ". $ This-> template_tag_right."/is ", $ content, $ match );
  216. $ Match = $ this-> preg_match_all ("include \ s + (.*?) ", $ Content );
  217. If (! Isset ($ match [1]) |! Is_array ($ match [1]) return $ content;
  218. Foreach ($ match [1] as $ match_key => $ match_value ){
  219. $ A = preg_split ("/\ s +/is", $ match_value );
  220. $ New_tag = array ();
  221. // Analysis element
  222. Foreach ($ a as $ t ){
  223. $ B = explode ('=', $ t );
  224. If (in_array ($ B [0], $ this-> tag_include )){
  225. If (! Empty ($ B [1]) {
  226. $ New_tag [$ B [0] = str_replace ("\" "," ", $ B [1]);
  227. } Else {
  228. Core: show_error ('The template path does not exist! ');
  229. }
  230. }
  231. }
  232. Extract ($ new_tag );
  233. // Query the template file
  234. Foreach ($ this-> conf ['view _ path'] as $ v ){
  235. $ Conf_view_tpl = $ v. $ file; // include template file
  236. If (is_file ($ conf_view_tpl )){
  237. $ C = $ this-> read_file ($ conf_view_tpl );
  238. $ Inc_file = str_replace ($ this-> _ tpl_suffix, '', basename ($ file ));
  239. $ This-> view_path_param = dirname ($ file ).'/';
  240. $ Compile_dirpath = $ this-> check_temp_compile ();
  241. $ Include_file = $ this-> template_replace ($ c, $ compile_dirpath, $ inc_file); // Parse
  242. Break;
  243. } Else {
  244. Core: show_error ('Template file does not exist. check the file carefully: '. $ conf_view_tpl );
  245. }
  246. }
  247. $ Content = str_replace ($ match [0] [$ match_key],' ', $ Content );
  248. }
  249. Return $ content;
  250. }
  251. /**
  252. * Parse foreach
  253. * Usage <{foreach from = $ lists item = value key = kk}>
  254. * @ Param $ content template content
  255. * @ Return html parsed content
  256. */
  257. Private function parse_foreach ($ content ){
  258. If (empty ($ content) return false;
  259. // Preg_match_all ("/". $ this-> template_tag_left. "foreach \ s + (.*?) ". $ This-> template_tag_right."/is ", $ content, $ match );
  260. $ Match = $ this-> preg_match_all ("foreach \ s + (.*?) ", $ Content );
  261. If (! Isset ($ match [1]) |! Is_array ($ match [1]) return $ content;
  262. Foreach ($ match [1] as $ match_key => $ value ){
  263. $ Split = preg_split ("/\ s +/is", $ value );
  264. $ Split = array_filter ($ split );
  265. $ New_tag = array ();
  266. Foreach ($ split as $ v ){
  267. $ A = explode ("=", $ v );
  268. If (in_array ($ a [0], $ this-> tag_foreach) {// filter tags that do not exist here
  269. $ New_tag [$ a [0] = $ a [1];
  270. }
  271. }
  272. $ Key = '';
  273. Extract ($ new_tag );
  274. $ Key = ($ key )? '$'. $ Key. '=> ':'';
  275. $ S =' ';
  276. $ Content = $ this-> str_replace ($ match [0] [$ match_key], $ s, $ content );
  277. }
  278. Return $ content;
  279. }
  280. /**
  281. * Match the end string
  282. */
  283. Private function parse_comm ($ content ){
  284. $ Search = array (
  285. "/". $ This-> template_tag_left. "\/foreach". $ this-> template_tag_right. "/is ",
  286. "/". $ This-> template_tag_left. "\/if". $ this-> template_tag_right. "/is ",
  287. "/". $ This-> template_tag_left. "else". $ this-> template_tag_right. "/is ",
  288. );
  289. $ Replace = array (
  290. " ",
  291. " ",
  292. " "
  293. );
  294. $ Content = preg_replace ($ search, $ replace, $ content );
  295. Return $ content;
  296. }
  297. /**
  298. * Check the compilation Directory. If no directory is created, recursively create the directory.
  299. * @ Param string $ path: complete file path
  300. * @ Return template content
  301. */
  302. Private function check_temp_compile (){
  303. // $ Paht = $ this-> template_c.
  304. $ Tpl_path = ($ this-> view_path_param )? $ This-> view_path_param: $ this-> get_tpl_path ();
  305. $ All_tpl_apth = $ this-> template_c. $ tpl_path;
  306. If (! Is_dir ($ all_tpl_apth )){
  307. $ This-> create_dir ($ tpl_path );
  308. }
  309. Return $ all_tpl_apth;
  310. }
  311. /**
  312. * Read files
  313. * @ Param string $ path: complete file path
  314. * @ Return template content
  315. */
  316. Private function read_file ($ path ){
  317. // $ This-> check_file_limits ($ path, 'r ');
  318. If ($ r = @ fopen ($ path, 'r') === false ){
  319. Core: show_error ('The template file has no read or execution permissions. Please check it! ');
  320. }
  321. $ Content = fread ($ r, filesize ($ path ));
  322. Fclose ($ r );
  323. Return $ content;
  324. }
  325. /**
  326. * Write a file
  327. * @ Param string $ filename file name
  328. * @ Param string $ content template content
  329. * @ Return file name
  330. */
  331. Private function compile_file ($ filename, $ content, $ dir ){
  332. If (empty ($ filename) core: show_error ("{$ filename} Creation failed ");
  333. $ Content = $ this-> body_content ($ content); // operations on the file content
  334. // Echo 'starts to compile ==== ';
  335. $ F = $ dir. $ filename. $ this-> tpl_compile_suffix;
  336. // $ This-> check_file_limits ($ f, 'w ');
  337. If ($ fp = @ fopen ($ f, 'WB ') === false ){
  338. Core: show_error ($ f .'
    Failed to compile the file. check the file permission .');
  339. }
  340. // Enable flock
  341. Flock ($ fp, LOCK_EX + LOCK_NB );
  342. Fwrite ($ fp, $ content, strlen ($ content ));
  343. Flock ($ fp, LOCK_UN + LOCK_NB );
  344. Fclose ($ fp );
  345. Return $ f;
  346. }
  347. /**
  348. * This file permission function is temporarily obsolete.
  349. * @ Param [$ path] [path]
  350. * @ Param [status] [w = write, r = read]
  351. */
  352. Public function check_file_limits ($ path, $ status = 'rw '){
  353. Clearstatcache ();
  354. If (! Is_writable ($ path) & $ status = 'w '){
  355. Core: show_error ("{$ path}
    No write permission. Please check .");
  356. } Elseif (! Is_readable ($ path) & $ status = 'r '){
  357. Core: show_error ("{$ path}
    No read permission. Please check .");
  358. } Elseif ($ status = 'rw ') {// check wirte and read
  359. If (! Is_writable ($ path) |! Is_readable ($ path )){
  360. Core: show_error ("{$ path}
    No write or read permission. Please check ");
  361. }
  362. }
  363. }
  364. /**
  365. * Read the first line of the compiled template and analyze it into an array.
  366. * @ Param string $ filepath file path
  367. * @ Param number $ line number of rows
  368. * @ Return returns the string of the specified number of rows.
  369. */
  370. /*
  371. Private function get_compile_header ($ filepath, $ line = 0 ){
  372. If ($ file_arr = @ file ($ filepath) === false ){
  373. Core: show_error ($ filepath .'
    Failed to read File. Please check file permission! ');
  374. }
  375. Return $ file_arr [0];
  376. }
  377. */
  378. /**
  379. * Date on which the header comment is analyzed
  380. * @ Param string $ the first line in the header of the cotnent compilation file
  381. * @ Return returns the last date
  382. */
  383. /*
  384. Private function get_compile_header_comment ($ content ){
  385. Preg_match ("/\/\*(.*?) \ * \ // ", $ Content, $ match );
  386. If (! Isset ($ match [1]) | empty ($ match [1]) core: show_error ('Compilation error! ');
  387. $ Arr = explode ('|', $ match [1]);
  388. $ Arr_date = explode ('#', $ arr [0]);
  389. Return $ arr_date [1];
  390. }
  391. */
  392. /**
  393. * Obtain the complete template path and return an existing file
  394. * @ Param string $ filename file name
  395. * @ Param string $ view_path template path
  396. * @ Return
  397. */
  398. Private function get_tpl ($ filename, $ view_path ){
  399. Empty ($ filename) & $ filename = $ this-> tpl_name;
  400. // Traverse the template path
  401. Foreach ($ this-> conf ['view _ path'] as $ path ){
  402. If ($ view_path) {// find the file directly from the tpl and Directory
  403. $ Tpl_path = $ path. $ view_path;
  404. $ View_file_path = $ tpl_path. $ filename. $ this-> _ tpl_suffix;
  405. } Else {// locate the file according to the Directory, controller, and method
  406. $ View_file_path = ($ tpl_path = $ this-> get_tpl_path ($ path ))? $ Tpl_path. $ filename. $ this-> _ tpl_suffix: exit (0 );
  407. }
  408. If (is_file ($ view_file_path )){
  409. // Transfer the template path and template name to the pointer
  410. $ This-> template_path = $ tpl_path ;//
  411. $ This-> template_name = $ filename. $ this-> _ tpl_suffix;
  412. Return true;
  413. } Else {
  414. Core: show_error ($ filename. $ this-> _ tpl_suffix. 'Template does not exist ');
  415. }
  416. }
  417. }
  418. /**
  419. * Obtain the template path
  420. * @ Param string $ path main directory
  421. * @ Return url d and M splicing paths
  422. */
  423. Private function get_tpl_path ($ path = ''){
  424. Core: get_directory_name () & $ path_arr [0] = core: get_directory_name ();
  425. Core: get_controller_name () & $ path_arr [1] = core: get_controller_name ();
  426. (Is_array ($ path_arr ))? $ Newpath = implode ('/', $ path_arr): core: show_error ('an error occurred while obtaining the template path! ');
  427. Return $ path. $ newpath .'/';
  428. }
  429. /**
  430. * Create a directory
  431. * @ Param string $ path directory
  432. * @ Return
  433. */
  434. Private function create_dir ($ path, $ mode = 0777 ){
  435. If (is_dir ($ path) return false;
  436. $ Dir_arr = explode ('/', $ path );
  437. $ Dir_arr = array_filter ($ dir_arr );
  438. $ Allpath = '';
  439. $ Newdir = $ this-> template_c;
  440. Foreach ($ dir_arr as $ dir ){
  441. $ Allpath = $ newdir. '/'. $ dir;
  442. If (! Is_dir ($ allpath )){
  443. $ Newdir = $ allpath;
  444. If (! @ Mkdir ($ allpath, $ mode )){
  445. Core: show_error ($ allpath .'
    Failed to create directory. Please check whether you have the write permission! ');
  446. }
  447. Chmod ($ allpath, $ mode );
  448. } Else {
  449. $ Newdir = $ allpath;
  450. }
  451. }
  452. Return true;
  453. }
  454. Public function _ destruct (){
  455. $ This-> vars = null;
  456. $ This-> view_path_param = null;
  457. }
  458. };

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.