PHP Template Parsing class

Source: Internet
Author: User
Tags flock php foreach php template vars
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, it will find the current Controller default index template
  5. Private $tpl _suffix = '. html ';//if config is not configured with a default suffix display
  6. Private $tpl _compile_suffix= '. tpl.php ';//compile template path
  7. Private $template _tag_left = ' <{';//template left label
  8. Private $template _tag_right = '}> ';//Template Right Tag
  9. Private $template _c = ";//Compile Directory
  10. Private $template _path = ";//Template full path
  11. Private $template _name = ";//Template name index.html
  12. The element that defines the label for each template
  13. Private $tag _foreach = Array (' From ', ' item ', ' key ');
  14. Private $tag _include = Array (' file ');//Currently only read template default path is supported
  15. Public function __construct ($conf) {
  16. $this->conf = & $conf;
  17. $this->template_c = $this->conf[' template_config ' [' Template_c '];//compile 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 Content
  28. * @return Array
  29. */
  30. Private Function Preg_match_all ($pattern, $content) {
  31. if (Empty ($pattern) | | empty ($content)) Core::show_error (' Find template tag 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. * not explained here.
  46. * @return
  47. */
  48. Public function assign ($key, $value) {
  49. $this->vars[$key] = $value;
  50. }
  51. /**
  52. * Render Page
  53. * @param
  54. * How to use 1
  55. * $this->view->display (' Error ', ' comm/');
  56. * The default is to refer to the TPL template with the directory, so comm/is tpl/comm/error.html
  57. * How to use 2
  58. * $this->view->display (' ErrorFile ');
  59. * Default point to Controller pinned folder
  60. * For example your domain name is http://heartphp/admin/index, then 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);//Get the TPL full path and route the path and name to the pointer
  65. if (! $tpl _path_arr) Core::show_error ($filename. $this->_tpl_suffix. ' Template does not exist ');
  66. Compile start
  67. $this->view_path_param = $view templates and directories passed by _path;//users.
  68. $this->compile ();
  69. }
  70. /**
  71. * Compiler 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 );//parsing
  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 current project configuration file
  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. * Parsing template syntax
  98. * @param $str Content
  99. * @param $compile _dirpath Template Compilation Directory
  100. * @param $vars _template_c_name template Compile 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 (' template content is empty! ');
  105. Handling the compilation header
  106. $compile _path = $compile _dirpath. $vars _template_c_name. $this->tpl_compile_suffix;//Compiling files
  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 expires compiling when the template tag has an include and is modified also recompile
  115. <{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
  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 {//compile file does not exist create his
  122. $ret _file = $this->compile_file ($vars _template_c_name, $str, $compile _dirpath);
  123. }
  124. return $ret _file;
  125. }
  126. /**
  127. * Template file Body
  128. * @param string $str content
  129. * @return HTML
  130. */
  131. Private Function Body_content ($STR) {
  132. Analytical
  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 label Common section
  152. $content = $this->parse_comm ($content);
  153. Switch to PHP code
  154. $content = $this->parse_php ($content);
  155. return $content;
  156. }
  157. /**
  158. * echo If the default direct <{$config [' domain ']}> turns into
  159. */
  160. Private Function Parse_echo ($content) {
  161. }
  162. /**
  163. * Convert to PHP
  164. * @param $content HTML template content
  165. * @return HTML to replace good 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 Judgment 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 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
  208. * Record a time to develop a debug mode when you execute a delete template compile file
  209. * How to use <{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 elements
  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 (' template path does not exist! ');
  229. }
  230. }
  231. }
  232. Extract ($new _tag);
  233. Query 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);//parsing
  242. Break
  243. } else {
  244. Core::show_error (' template file does not exist, please double check the file: '. $conf _view_tpl);
  245. }
  246. }
  247. $content = Str_replace ($match [0][$match _key], " , $content);
  248. }
  249. return $content;
  250. }
  251. /**
  252. * Parsing foreach
  253. * How to use <{foreach from= $lists item=value key=kk}>
  254. * @param $content Template content
  255. * @return The content after parsing HTML
  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)) {//Here Filter label does not exist filter
  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 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 compilation directory if not created, recursively create directory
  299. * @param string $path file full 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 File
  313. * @param string $path file full 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 (' template file does not have read or EXECUTE permission, please check! ');
  320. }
  321. $content = Fread ($r, FileSize ($path));
  322. Fclose ($R);
  323. return $content;
  324. }
  325. /**
  326. * Write files
  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);//operation on file contents
  334. Echo ' started compiling the ===== ';
  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 file, please check file permissions. ');
  339. }
  340. Open 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 check file permission function is temporarily discarded.
  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 the array
  366. * @param string $filepath file path
  367. * Number $line rows @param
  368. * @return A string that returns 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 permissions! ');
  374. }
  375. return $file _arr[0];
  376. }
  377. */
  378. /**
  379. * Analyze the date of the header comment
  380. * @param string $cotnent Compile the first line of the file header
  381. * @return return 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 (' Compile error! ');
  387. $arr = Explode (' | ', $match [1]);
  388. $arr _date = Explode (' # # ', $arr [0]);
  389. return $arr _date[1];
  390. }
  391. */
  392. /**
  393. * Get template full path and return 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 template Path
  401. foreach ($this->conf[' View_path ') as $path) {
  402. if ($view _path) {//Find files directly from the TPL and directory
  403. $tpl _path = $path. $view _path;
  404. $view _file_path = $tpl _path. $filename. $this->_tpl_suffix;
  405. } else {//based on directory, controller, method start looking for file
  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 template path and template name to 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. * Get template path
  420. * @param string $path home directory
  421. * @return The stitching path of the URL D and M
  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 (' Get template path failed! ');
  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 if you have 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. };
Copy Code
  • 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.