国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > PHP > 正文

PHP模板解析類實(shí)例

2024-05-04 23:37:36
字體:
供稿:網(wǎng)友

這篇文章主要介紹了PHP模板解析類,涉及php針對模板文件的解析與字符串處理的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下

本文實(shí)例講述了PHP模板解析類。分享給大家供大家參考。具體如下:

 

 
  1. <?php 
  2. class template { 
  3. private $vars = array(); 
  4. private $conf = ''
  5. private $tpl_name = 'index'
  6. //如果模板不存在 會查找當(dāng)前 controller默認(rèn)index模板 
  7. private $tpl_suffix = '.html';//如果CONFIG沒配置默認(rèn)后綴 則顯示 
  8. private $tpl_compile_suffix= '.tpl.php';//編譯模板路徑 
  9. private $template_tag_left = '<{';//模板左標(biāo)簽 
  10. private $template_tag_right = '}>';//模板右標(biāo)簽 
  11. private $template_c = '';//編譯目錄 
  12. private $template_path = '';//模板完整路徑  
  13. private $template_name = '';//模板名稱 index.html 
  14. //定義每個模板的標(biāo)簽的元素 
  15. private $tag_foreach = array('from''item''key'); 
  16. private $tag_include = array('file');//目前只支持讀取模板默認(rèn)路徑 
  17. public function __construct($conf) { 
  18. $this->conf = &$conf; 
  19. $this->template_c = $this->conf['template_config']['template_c'];//編譯目錄 
  20. $this->_tpl_suffix = $this->tpl_suffix(); 
  21. private function str_replace($search, $replace, $content) { 
  22. if(empty($search) || empty($replace) || empty($content)) return false
  23. return str_replace($search, $replace, $content); 
  24. /** 
  25. * preg_match_all 
  26. * @param $pattern 正則 
  27. * @param $content 內(nèi)容 
  28. * @return array 
  29. */ 
  30. private function preg_match_all($pattern, $content) { 
  31. if(empty($pattern) || empty($content)) core::show_error('查找模板標(biāo)簽失敗!'); 
  32. preg_match_all("/".$this->template_tag_left.$pattern.$this->template_tag_right."/is", $content, $match); 
  33. return $match; 
  34. /** 
  35. * 模板文件后綴  
  36. */ 
  37. public function tpl_suffix() { 
  38. $tpl_suffix = empty($this->conf['template_config']['template_suffix']) ?  
  39. $this->tpl_suffix :  
  40. $this->conf['template_config']['template_suffix'] ; 
  41. return $tpl_suffix; 
  42. /** 
  43. * 此處不解釋了 
  44. * @return  
  45. */ 
  46. public function assign($key, $value) { 
  47. $this->vars[$key] = $value; 
  48. /** 
  49. * 渲染頁面 
  50. * @param  
  51. * 使用方法 1 
  52. * $this->view->display('error', 'comm/'); 
  53. * 默認(rèn)是指向TPL模版的跟目錄,所以comm/就是 tpl/comm/error.html 
  54. * 使用方法 2 
  55. * $this->view->display('errorfile');  
  56. * 默認(rèn)指向控制器固定的文件夾 
  57. * 例如你的域名是 http://heartphp/admin/index, 那么正確路徑就是tpl/admin/index/errorfile.html 
  58. * @return  
  59. */ 
  60. public function display($filename = '', $view_path = '') { 
  61. $tpl_path_arr = $this->get_tpl($filename, $view_path);//獲取TPL完整路徑 并且向指針傳送路徑以及名稱 
  62. if(!$tpl_path_arr) core::show_error($filename.$this->_tpl_suffix.'模板不存在'); 
  63. //編譯開始 
  64. $this->view_path_param = $view_path;//用戶傳遞過來的模版跟目錄 
  65. $this->compile(); 
  66. /** 
  67. * 編譯控制器 
  68. * @param  
  69. * @return  
  70. */ 
  71. private function compile() { 
  72. $filepath = $this->template_path.$this->template_name; 
  73. $compile_dirpath = $this->check_temp_compile(); 
  74. $vars_template_c_name = str_replace($this->_tpl_suffix, '', $this->template_name); 
  75. $include_file = $this->template_replace($this->read_file($filepath), $compile_dirpath, $vars_template_c_name);//解析 
  76. if($include_file) { 
  77. $this->read_config() && $config = $this->read_config(); 
  78. extract($this->vars, EXTR_SKIP); 
  79. [url=home.php?mod=space&uid=48608]@include[/url] $include_file; 
  80. /** 
  81. * 讀取當(dāng)前項(xiàng)目配置文件 
  82. */ 
  83. protected function read_config() { 
  84. if(file_exists(SYSTEM_PATH.'conf/config.php')) { 
  85. @include SYSTEM_PATH.'conf/config.php';  
  86. return $config; 
  87. return false
  88. /** 
  89. * 解析模板語法 
  90. * @param $str 內(nèi)容 
  91. * @param $compile_dirpath 模版編譯目錄 
  92. * @param $vars_template_c_name 模版編譯文件名 
  93. * @return 編譯過的PHP模板文件名 
  94. */ 
  95. private function template_replace($str, $compile_dirpath, $vars_template_c_name) { 
  96. if(empty($str)) core::show_error('模板內(nèi)容為空!'); 
  97. //處理編譯頭部 
  98. $compile_path = $compile_dirpath.$vars_template_c_name.$this->tpl_compile_suffix;//編譯文件 
  99. if(is_file($compile_path)) { 
  100. //$header_content = $this->get_compile_header($compile_path); 
  101. //$compile_date = $this->get_compile_header_comment($header_content); 
  102. $tpl_filemtime = filemtime($this->template_path.$this->template_name); 
  103. $compile_filemtime = filemtime($compile_path); 
  104. //echo $tpl_filemtime.'=='.date('Y-m-d H:i:s', $tpl_filemtime).'<br/>'; 
  105. //echo $compile_filemtime.'=='.date('Y-m-d H:i:s', $compile_filemtime); 
  106. //如果文件過期編譯 當(dāng)模板標(biāo)簽有include并且有修改時(shí) 也重新編譯 
  107. //<{include file="public/left.html"}> 當(dāng)修改include里的文件,非DEBUG模式時(shí) 如果不更改主文件 目前是不重新編譯include里的文件,我在考慮是否也要更改,沒想好,暫時(shí)這樣,所以在開發(fā)階段一定要開啟DEBUG=1模式 要不然修改include文件無效 。 有點(diǎn)羅嗦,不知道表述清楚沒 
  108. if($tpl_filemtime > $compile_filemtime || DEBUG) { 
  109. $ret_file = $this->compile_file($vars_template_c_name, $str, $compile_dirpath); 
  110. else { 
  111. $ret_file = $compile_path; 
  112. else {//編譯文件不存在 創(chuàng)建他 
  113. $ret_file = $this->compile_file($vars_template_c_name, $str, $compile_dirpath); 
  114. return $ret_file; 
  115. /** 
  116. * 模板文件主體 
  117. * @param string $str 內(nèi)容 
  118. * @return html 
  119. */ 
  120. private function body_content($str) { 
  121. //解析 
  122. $str = $this->parse($str); 
  123. $header_comment = "Create On##".time()."|Compiled from##".$this->template_path.$this->template_name; 
  124. $content = "<? if(!defined('IS_HEARTPHP')) exit('Access Denied');/*{$header_comment}*/?>/r/n$str"
  125. return $content; 
  126. /** 
  127. * 開始解析相關(guān)模板標(biāo)簽 
  128. * @param $content 模板內(nèi)容 
  129. */ 
  130. private function parse($content) { 
  131. //foreach 
  132. $content = $this->parse_foreach($content); 
  133. //include 
  134. $content = $this->parse_include($content); 
  135. //if 
  136. $content = $this->parse_if($content); 
  137. //elseif 
  138. $content = $this->parse_elseif($content); 
  139. //模板標(biāo)簽公用部分 
  140. $content = $this->parse_comm($content);  
  141. //轉(zhuǎn)為PHP代碼 
  142. $content = $this->parse_php($content); 
  143. return $content; 
  144. /** 
  145. * echo 如果默認(rèn)直接<{$config['domain']}> 轉(zhuǎn)成 <?php echo $config['domain']?> 
  146. */ 
  147. private function parse_echo($content) { 
  148. /** 
  149. * 轉(zhuǎn)換為PHP 
  150. * @param $content html 模板內(nèi)容 
  151. * @return html 替換好的HTML 
  152. */ 
  153. private function parse_php($content){ 
  154. if(empty($content)) return false
  155. $content = preg_replace("/".$this->template_tag_left."(.+?)".$this->template_tag_right."/is""<?php $1 ?>", $content); 
  156. return $content; 
  157. /** 
  158. * if判斷語句 
  159. * <{if empty($zhang)}> 
  160. * zhang 
  161. * <{elseif empty($liang)}> 
  162. * liang 
  163. * <{else}> 
  164. * zhangliang 
  165. * <{/if}> 
  166. */ 
  167. private function parse_if($content) { 
  168. if(empty($content)) return false
  169. //preg_match_all("/".$this->template_tag_left."if/s+(.*?)".$this->template_tag_right."/is", $content, $match); 
  170. $match = $this->preg_match_all("if/s+(.*?)", $content); 
  171. if(!isset($match[1]) || !is_array($match[1])) return $content; 
  172. foreach($match[1] as $k => $v) { 
  173. //$s = preg_split("//s+/is", $v); 
  174. //$s = array_filter($s); 
  175. $content = str_replace($match[0][$k], "<?php if({$v}) { ?>", $content); 
  176. return $content; 
  177. private function parse_elseif($content) { 
  178. if(empty($content)) return false
  179. //preg_match_all("/".$this->template_tag_left."elseif/s+(.*?)".$this->template_tag_right."/is", $content, $match); 
  180. $match = $this->preg_match_all("elseif/s+(.*?)", $content); 
  181. if(!isset($match[1]) || !is_array($match[1])) return $content; 
  182. foreach($match[1] as $k => $v) { 
  183. //$s = preg_split("//s+/is", $v); 
  184. //$s = array_filter($s); 
  185. $content = str_replace($match[0][$k], "<?php } elseif ({$v}) { ?>", $content); 
  186. return $content; 
  187. /** 
  188. * 解析 include include標(biāo)簽不是實(shí)時(shí)更新的 當(dāng)主體文件更新的時(shí)候 才更新標(biāo)簽內(nèi)容,所以想include生效 請修改一下主體文件 
  189. * 記錄一下 有時(shí)間開發(fā)一個當(dāng)DEBUG模式的時(shí)候 每次執(zhí)行刪除模版編譯文件 
  190. * 使用方法 <{include file="www.phpddt.com"}> 
  191. * @param $content 模板內(nèi)容 
  192. * @return html 
  193. */ 
  194. private function parse_include($content) { 
  195. if(empty($content)) return false
  196. //preg_match_all("/".$this->template_tag_left."include/s+(.*?)".$this->template_tag_right."/is", $content, $match); 
  197. $match = $this->preg_match_all("include/s+(.*?)", $content); 
  198. if(!isset($match[1]) || !is_array($match[1])) return $content; 
  199. foreach($match[1] as $match_key => $match_value) { 
  200. $a = preg_split("//s+/is", $match_value); 
  201. $new_tag = array(); 
  202. //分析元素 
  203. foreach($a as $t) { 
  204. $b = explode('=', $t); 
  205. if(in_array($b[0], $this->tag_include)) { 
  206. if(!empty($b[1])) { 
  207. $new_tag[$b[0]] = str_replace("/"""", $b[1]); 
  208. else { 
  209. core::show_error('模板路徑不存在!'); 
  210. extract($new_tag); 
  211. //查詢模板文件 
  212. foreach($this->conf['view_path'] as $v){ 
  213. $conf_view_tpl = $v.$file;//include 模板文件 
  214. if(is_file($conf_view_tpl)) { 
  215. $c = $this->read_file($conf_view_tpl); 
  216. $inc_file = str_replace($this->_tpl_suffix, '', basename($file)); 
  217. $this->view_path_param = dirname($file).'/'
  218. $compile_dirpath = $this->check_temp_compile(); 
  219. $include_file = $this->template_replace($c, $compile_dirpath, $inc_file);//解析 
  220. break
  221. else { 
  222. core::show_error('模板文件不存在,請仔細(xì)檢查 文件:'. $conf_view_tpl); 
  223. }  
  224. $content = str_replace($match[0][$match_key], '<?php include("'.$include_file.'")?>', $content); 
  225. return $content; 
  226. /** 
  227. * 解析 foreach 
  228. * 使用方法 <{foreach from=$lists item=value key=kk}> 
  229. * @param $content 模板內(nèi)容 
  230. * @return html 解析后的內(nèi)容 
  231. */ 
  232. private function parse_foreach($content) { 
  233. if(empty($content)) return false
  234. //preg_match_all("/".$this->template_tag_left."foreach/s+(.*?)".$this->template_tag_right."/is", $content, $match); 
  235. $match = $this->preg_match_all("foreach/s+(.*?)", $content); 
  236. if(!isset($match[1]) || !is_array($match[1])) return $content; 
  237. foreach($match[1] as $match_key => $value) { 
  238. $split = preg_split("//s+/is", $value); 
  239. $split = array_filter($split); 
  240. $new_tag = array(); 
  241. foreach($split as $v) { 
  242. $a = explode("=", $v); 
  243. if(in_array($a[0], $this->tag_foreach)) {//此處過濾標(biāo)簽 不存在過濾 
  244. $new_tag[$a[0]] = $a[1]; 
  245. $key = ''
  246. extract($new_tag); 
  247. $key = ($key) ? ' 
  248. 希望本文所述對大家的php程序設(shè)計(jì)有所幫助。 
  249.  
  250. .$key.' =>' : '' ; 
  251.  
  252.  
  253. $s = '<?php foreach('.$from.' as '.$key.'  
  254. 希望本文所述對大家的php程序設(shè)計(jì)有所幫助。 
  255.  
  256. .$item.') { ?>'
  257.  
  258.  
  259. $content = $this->str_replace($match[0][$match_key], $s, $content); 
  260. return $content; 
  261. /** 
  262. * 匹配結(jié)束 字符串 
  263. */ 
  264. private function parse_comm($content) { 
  265. $search = array( 
  266. "/".$this->template_tag_left."//foreach".$this->template_tag_right."/is"
  267. "/".$this->template_tag_left."//if".$this->template_tag_right."/is"
  268. "/".$this->template_tag_left."else".$this->template_tag_right."/is"
  269. ); 
  270. $replace = array( 
  271. "<?php } ?>"
  272. "<?php } ?>"
  273. "<?php } else { ?>" 
  274. ); 
  275. $content = preg_replace($search, $replace, $content); 
  276. return $content; 
  277. /** 
  278. * 檢查編譯目錄 如果沒有創(chuàng)建 則遞歸創(chuàng)建目錄 
  279. * @param string $path 文件完整路徑 
  280. * @return 模板內(nèi)容 
  281. */ 
  282. private function check_temp_compile() { 
  283. //$paht = $this->template_c. 
  284. $tpl_path = ($this->view_path_param) ? $this->view_path_param : $this->get_tpl_path() ; 
  285. $all_tpl_apth = $this->template_c.$tpl_path; 
  286. if(!is_dir($all_tpl_apth)) { 
  287. $this->create_dir($tpl_path); 
  288. return $all_tpl_apth; 
  289. /** 
  290. * 讀文件 
  291. * @param string $path 文件完整路徑 
  292. * @return 模板內(nèi)容 
  293. */ 
  294. private function read_file($path) { 
  295. //$this->check_file_limits($path, 'r'); 
  296. if(($r = @fopen($path, 'r')) === false) { 
  297. core::show_error('模版文件沒有讀取或執(zhí)行權(quán)限,請檢查!'); 
  298. $content = fread($r, filesize($path)); 
  299. fclose($r); 
  300. return $content; 
  301. /** 
  302. * 寫文件 
  303. * @param string $filename 文件名 
  304. * @param string $content 模板內(nèi)容 
  305. * @return 文件名 
  306. */ 
  307. private function compile_file($filename, $content, $dir) { 
  308. if(empty($filename)) core::show_error("{$filename} Creation failed"); 
  309. $content = $this->body_content($content);//對文件內(nèi)容操作 
  310. //echo '開始編譯了====='; 
  311. $f = $dir.$filename.$this->tpl_compile_suffix; 
  312. //$this->check_file_limits($f, 'w'); 
  313. if(($fp = @fopen($f, 'wb')) === false) { 
  314. core::show_error($f.'<br/>編譯文件失敗,請檢查文件權(quán)限.'); 
  315. //開啟flock 
  316. flock($fp, LOCK_EX + LOCK_NB); 
  317. fwrite($fp, $content, strlen($content)); 
  318. flock($fp, LOCK_UN + LOCK_NB); 
  319. fclose($fp); 
  320. return $f; 
  321. /** 
  322. * 這個檢查文件權(quán)限函數(shù) 暫時(shí)廢棄了 
  323. * @param [$path] [路徑] 
  324. * @param [status] [w=write, r=read] 
  325. */ 
  326. public function check_file_limits($path , $status = 'rw') { 
  327. clearstatcache(); 
  328. if(!is_writable($path) && $status == 'w') { 
  329. core::show_error("{$path}<br/>沒有寫入權(quán)限,請檢查."); 
  330. } elseif(!is_readable($path) && $status == 'r') { 
  331. core::show_error("{$path}<br/>沒有讀取權(quán)限,請檢查."); 
  332. } elseif($status == 'rw') {//check wirte and read 
  333. if(!is_writable($path) || !is_readable($path)) { 
  334. core::show_error("{$path}<br/>沒有寫入或讀取權(quán)限,請檢查"); 
  335. /** 
  336. * 讀取編譯后模板的第一行 并分析成數(shù)組 
  337. * @param string $filepath 文件路徑 
  338. * @param number $line 行數(shù) 
  339. * @return 返回指定行數(shù)的字符串  
  340. */ 
  341. /* 
  342. private function get_compile_header($filepath, $line = 0) { 
  343. if(($file_arr = @file($filepath)) === false) { 
  344. core::show_error($filepath.'<br/>讀取文件失敗,請檢查文件權(quán)限!'); 
  345. } 
  346. return $file_arr[0]; 
  347. } 
  348. */ 
  349. /** 
  350. * 分析頭部注釋的日期 
  351. * @param string $cotnent 編譯文件頭部第一行 
  352. * @return 返回上一次日期  
  353. */ 
  354. /* 
  355. private function get_compile_header_comment($content) { 
  356. preg_match("////*(.*?)/*///", $content, $match); 
  357. if(!isset($match[1]) || empty($match[1])) core::show_error('編譯錯誤!');  
  358. $arr = explode('|', $match[1]); 
  359. $arr_date = explode('##', $arr[0]); 
  360. return $arr_date[1]; 
  361. } 
  362. */ 
  363. /** 
  364. * 獲取模板完整路徑 并返回已存在文件 
  365. * @param string $filename 文件名 
  366. * @param string $view_path 模板路徑  
  367. * @return  
  368. */ 
  369. private function get_tpl($filename, $view_path) { 
  370. empty($filename) && $filename = $this->tpl_name; 
  371. //遍歷模板路徑 
  372. foreach($this->conf['view_path'] as $path) { 
  373. if($view_path) {//直接從tpl跟目錄找文件 
  374. $tpl_path = $path.$view_path; 
  375. $view_file_path = $tpl_path.$filename.$this->_tpl_suffix; 
  376. else {//根據(jù)目錄,控制器,方法開始找文件 
  377. $view_file_path = ($tpl_path = $this->get_tpl_path($path)) ? $tpl_path.$filename.$this->_tpl_suffix : exit(0); 
  378. if(is_file($view_file_path)) { 
  379. //向指針傳送模板路徑和模板名稱 
  380. $this->template_path = $tpl_path;// 
  381. $this->template_name = $filename.$this->_tpl_suffix; 
  382. return true
  383. else { 
  384. core::show_error($filename.$this->_tpl_suffix.'模板不存在'); 
  385. /** 
  386. * 獲取模板路徑 
  387. * @param string $path 主目錄 
  388. * @return URL D和M的拼接路徑 
  389. */ 
  390. private function get_tpl_path($path = '') { 
  391. core::get_directory_name() && $path_arr[0] = core::get_directory_name(); 
  392. core::get_controller_name() && $path_arr[1] = core::get_controller_name(); 
  393. (is_array($path_arr)) ? $newpath = implode('/', $path_arr) : core::show_error('獲取模板路徑失敗!') ; 
  394. return $path.$newpath.'/'
  395. /** 
  396. * 創(chuàng)建目錄 
  397. * @param string $path 目錄 
  398. * @return  
  399. */ 
  400. private function create_dir($path, $mode = 0777){ 
  401. if(is_dir($path)) return false
  402. $dir_arr = explode('/', $path); 
  403. $dir_arr = array_filter($dir_arr); 
  404. $allpath = ''
  405. $newdir = $this->template_c; 
  406. foreach($dir_arr as $dir) { 
  407. $allpath = $newdir.'/'.$dir; 
  408. if(!is_dir($allpath)) { 
  409. $newdir = $allpath; 
  410. if(!@mkdir($allpath, $mode)) { 
  411. core::show_error( $allpath.'<br/>創(chuàng)建目錄失敗,請檢查是否有可都寫權(quán)限!'); 
  412. chmod($allpath, $mode); 
  413. else { 
  414. $newdir = $allpath; 
  415. return true
  416. public function __destruct(){ 
  417. $this->vars = null
  418. $this->view_path_param = null

希望本文所述對大家的php程序設(shè)計(jì)有所幫助。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 青铜峡市| 台中县| 玉山县| 东方市| 富阳市| 虞城县| 分宜县| 方城县| 阳西县| 工布江达县| 广丰县| 顺平县| 乌拉特中旗| 玉溪市| 石泉县| 合山市| 嘉祥县| 静宁县| 太白县| 韶山市| 宁城县| 潼关县| 家居| 临澧县| 宁陕县| 伽师县| 岱山县| 永寿县| 白玉县| 长武县| 涟水县| 寿宁县| 姜堰市| 四子王旗| 张北县| 康马县| 娱乐| 永清县| 镇江市| 承德县| 大石桥市|