首頁  >  文章  >  後端開發  >  Discuz的模板引擎

Discuz的模板引擎

WBOY
WBOY原創
2016-07-25 09:06:181352瀏覽
Discuz的模板引擎

Discuz的模板引擎一個比較好的模板引擎類,很久以前就在網上找到,目測這個Discuz的模板引擎應該很老了,是DZ7.2以前的版本了,自己也用得很順手,分享下這個模板類別。

有兩個檔案。一個模板類,一個模板替換中需要用到的函數
原文位址:http://blog.qita.in

  1. ?/**
  2. * 範本類別 - 使用 Discuz 範本引擎解析
  3. * http://blog.qita.in
  4. */
  5. require_once (DIR_ROOT . '/../function/template.func.php' );
  6. class Template {
  7. const DIR_SEP = DIRECTORY_SEPARATOR;
  8. /**
  9. * 範本實例
  10. *
  11. * @staticvar
  12. * @var object Template
  13. */
  14. protected static/_instance;
  15. * 模板參數資訊
  16. *
  17. * @var array
  18. */
  19. protected static> $_instance;
  20. * 單件模式呼叫方法
  21. *
  22. * @static
  23. * @return object Template
  24. */
  25. protected $_options = array();
  26. /**
  27. * 建構方法
  28. *
  29. * @return void
  30. */
  31. public static function getInstance() {
  32. if (!self :: $_instance instance )
  33. self :: $_instance = new self();
  34. return self :: $_instance;
  35. }
  36. /**
  37. * 設定範本參數資訊
  38. *
  39. * @param array $options 參數陣列
  40. * @return void
  41. */
  42. privstructate function __vstructate( ) {
  43. $this -> _options = array('template_dir' => 'templates' . self :: DIR_SEP, // 模板檔案所在目錄
  44. 'cache_dir' => 'templates' . self :: DIR_SEP . 'cache' . self :: DIR_SEP, // 快取檔案存放目錄
  45. 'auto_update' => false, // 當範本檔案變更時是否重新產生快取
  46. 'cache_lifetime' => 0, // 快取生命週期(分鐘),為0 表示永久
  47. );
  48. }
  49. /**
  50. * 設定範本參數
  51. *
  52. * @param string $name 參數名稱
  53. * @param mixed $value 參數值
  54. * @return void
  55. */
  56. public function setOptions(array $options) {
  57. foreach ($ options as $name => $value)
  58. $this -> set($name, $value);
  59. }
  60. /**
  61. * 透過魔術方法設定範本參數
  62. *
  63. * @see Template::set()
  64. * @param string $name 參數名稱
  65. * @param mixed $value 參數值
  66. * @return void
  67. */
  68. public function set( $name, $value) {
  69. switch ($name) {
  70. case 'template_dir':
  71. $value = $this -> _trimpath($value);
  72. if (!file_exists($value ))
  73. $this -> _throwException("找不到指定的模板目錄"$value"");
  74. $this -> _options['template_dir'] = $value;
  75. break;
  76. case 'cache_dir':
  77. $value = $this -> _trimpath($value);
  78. if (!file_exists($value))
  79. $this -> _throwException("找不到指定的快取目錄" $value"");
  80. $this -> _options['cache_dir'] = $value;
  81. break;
  82. case 'auto_update':
  83. $this -> _options['auto_update'] = (boolean) $value;
  84. break;
  85. case 'cache_lifetime':
  86. $this -> _options['cache_lifetime'] = (float) $value;
  87. break;
  88. default:
  89. $this -> _throwException("未知的範本設定選項"$name"");
  90. }
  91. }
  92. /**
  93. * 取得範本檔案
  94. *
  95. * @param string $file 範本檔案名稱
  96. * @return string
  97. */
  98. public function __set( $name, $value) {
  99. $this -> set($name, $value);
  100. }
  101. /**
  102. * 檢測模板文件是否需要更新緩存
  103. *
  104. * @param string $file 模板文件名稱
  105. * @param string $md5data 模板文件md5 校驗信息
  106. * @param integer $ md5data 範本檔案到期時間校驗資訊
  107. * @return void
  108. */
  109. public function getfile($file ) {
  110. $cachefile = $this -> _getCacheFile($file);
  111. if (!file_exists($cachefile))
  112. $this -> cache($file); return $cachefile;
  113. }
  114. /**
  115. * 將範本檔案快取
  116. *
  117. * @param string $file 範本檔案名稱
  118. * @return void
  119. */
  120. public function check($file, $md5data, $expireTime) {
  121. if ($this -> _options['auto_update'] && md5_file($this -> _getTplFile($file)) != $md5data)
  122. $this -> cache($file);
  123. if ($this -> _options['cache_lifetime'] != 0 &&& (time() - $expireTime >= $this -> _options['cache_lifetime'] * 60))
  124. $this -> cache($file);
  125. }
  126. /***/
  127. public function cache($file) {
  128. $tplfile = $this -> _getTplFile($file);
  129. if (!is_readable($tplfile)) {
  130. if (!is_readable($tplfile)) {
  131. $this -> _throwException("範本檔案"$tplfile" 找不到或無法開啟");
  132. }
  133. // 取得範本內容
  134. $template = file_get_contents($tplfile);
  135. //過濾
  136. $template = preg_replace("//s", "{\1}", $template);
  137. // 取代語言包變數
  138. // $template = preg_replace("/{langs+(.+?)}/ies", "languagevar('\1')", $template);
  139. / / 取代PHP 換行符號 $template = str_replace("{LF}", "="\n"?>", $template);
  140. // 取代直接變數輸出
  141. $varRegexp = "((\$[a-zA-Z_x7f-xff][a- zA-Z0-9_x7f-xff]*)"
  142. . "([[a-zA-Z0-9_-."'[]$x7f-xff]+])*)";
  143. $template = preg_replace("/{(\$[a-zA-Z0-9_[]'"$.x7f-xff]+)}/s", "=\1?>", $template);
  144. $template = preg_replace("/$varRegexp/es", "addquote('=\1?>')", $template);
  145. $template = preg_replace("/==$varRegexp ?>?>/es", "addquote('=\1?>')", $template);
  146. // 取代範本載入指令
  147. $template = preg_replace("/[nrt] *{templates+([a-z0-9_]+)}[nrt]*/is",
  148. "rn include($template->getfile('\1')); ?>rn",
  149. $template
  150. );
  151. $template = preg_replace("/[nrt]*{templates+(.+?)}[nrt]*/is",
  152. "rn include($template ->getfile(\1)); ?>rn",
  153. $template
  154. );
  155. // 取代特定函數
  156. $template = preg_replace("/[nrt]*{evals+(. +?)}[nrt]*/ies",
  157. "stripvtags(' \1 ?>','')",
  158. $template
  159. );
  160. $template = preg_replace( "/[nrt]*{echos+(.+?)}[nrt]*/ies",
  161. "stripvtags(' echo \1; ?>','')",
  162. $template
  163. );
  164. $template = preg_replace("/([nrt]*){elseifs+(.+?)}([nrt]*)/ies",
  165. "stripvtags('\1 } elseif(\2) { ?>\3','')",
  166. $template
  167. );
  168. $template = preg_replace("/([nrt]*){else}([nrt] *)/is",
  169. "\1 } else { ?>\2",
  170. $template
  171. );
  172. // 取代循環函數及條件判斷語句
  173. $nest = 5;
  174. for ($i = 0; $i $template = preg_replace("/[nrt]*{loops+(S+)s+(S+)}[nr] *(.+?)[nr]*{/loop}[nrt]*/ies",
  175. "stripvtags(' if(is_array(\1)) { foreach(\1 as \2) { ? >','\3 } } ?>')",
  176. $template
  177. );
  178. $template = preg_replace("/[nrt]*{loops+(S+)s+(S+)s+ (S+)}[nrt]*(.+?)[nrt]*{/loop}[nrt]*/ies",
  179. "stripvtags(' if(is_array(\1)) { foreach(\ 1 as \2 => \3) { ?>','\4 } } ?>')",
  180. $template
  181. );
  182. $template = preg_replace("/([nrt ]*){ifs+(.+?)}([nr]*)(.+?)([nr]*){/if}([nrt]*)/ies",
  183. "stripvtags('\ 1 if(\2) { ?>\3','\4\5 } ?>\6')",
  184. $template
  185. );
  186. }
  187. //常數替換
  188. $template = preg_replace("/{([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)}/s",
  189. "=\1 ?>",
  190. $template
  191. );
  192. // 刪除PHP 程式碼斷間多餘的空格及換行
  193. $template = preg_replace("/ ?>[nr]* /s" , " ", $template);
  194. // 其他替換
  195. $template = preg_replace("/"(http)?[w./:]+?[^"]+?&[^"]+ ?"/e",
  196. "transamp('\0')",
  197. $template
  198. );
  199. $template = preg_replace("/<script>]*?src=" (.+?)".*?>s*</script>/ise",
  200. "stripscriptamp('\1')",
  201. $template
  202. );
  203. $template = preg_replace ("/[nrt]*{blocks+([a-zA-Z0-9_]+)}(.+?){/block}/ies",
  204. "stripblock('\1', '\2' )",
  205. $template
  206. );
  207. // 新增md5 及過期校驗
  208. $md5data = md5_file($tplfile);
  209. $expireTime = time();
  210. $ template = " if (!class_exists('template')) die('Access Denied');"
  211. . "$template->getInstance()->check('$file', '$md5data', $expireTime);"
  212. . "?>rn$template";
  213. // 寫入快取檔案
  214. $cachefile = $this -> _getCacheFile($file);
  215. $makepath = $this -> _makepath($cachefile);
  216. if ($makepath !== true)
  217. $this -> _throwException("無法建立快取目錄"$makepath"");
  218. file_put_contents($cachefile, $ template);
  219. }
  220. /**
  221. * 將路徑修正為適合作業系統的形式
  222. *
  223. * @param string $path 路徑名稱
  224. * @return string
  225. */
  226. protected function _trimpath($path) {
  227. return str_replace(array('/', '\', '/ /', '\\'), self :: DIR_SEP, $path);
  228. }
  229. /**
  230. * 取得範本檔案名稱及路徑
  231. *
  232. * @param string $file 範本檔案名稱
  233. * @return string
  234. */
  235. protected function _getTplFile($file) {
  236. return $this -> _trimpath($this -> _options['template_dir'] . self :: DIR_SEP . $file);
  237. }
  238. /**
  239. * 取得範本快取檔案名稱及路徑
  240. *
  241. * @param string $file 範本檔案名稱
  242. * @return string
  243. */
  244. protected function _getCacheFile($file) {
  245. $file = preg_replace('/.[a-z0-9-_]+$/i' , '.cache.php', $file);
  246. 回傳$this -> _trimpath($this -> _options['cache_dir'] . self :: DIR_SEP . $file);
  247. }
  248. /**
  249. * 根據指定的路徑建立不存在的資料夾
  250. *
  251. * @param string $path 路徑/資料夾名稱
  252. * @return string
  253. */
  254. protected function _makepath($path ) {
  255. $dirs =explode(self :: DIR_SEP, dirname($this -> _trimpath($path))); $tmp = '';
  256. foreach ($dirs as $dir) {
  257. $tmp .= $dir 。 $tmp, 0777))
  258. return $tmp;
  259. }
  260. return true;
  261. }
  262. /**
  263. * 拋出一個錯誤訊息
  264. *
  265. * @param string $message
  266. * @return void
  267. */
  268. protected function _throwted function _throwted func. ) {
  269. throw new Exception($message);
  270. }
  271. }
  272. ?> ;
複製程式碼>
範本函數檔
    /**
  1. * 範本替換中需要用到的函數
  2. * http://blog.qita.in
  3. */
  4. function transamp($template) {
  5. $ template = str_replace('&', '&', $template);
  6. $template = str_replace('&', '&', $template);
  7. $template = str_replace(' "', '"' , $template);
  8. return $template;
  9. }
  10. function stripvtags($expr, $statement) {
  11. $expr = str_replace("\"" , """, preg_replace", preg_replace("\""" , """, preg_replace ("/=(\$.+?)?>/s", "\1", $expr));
  12. $statement = str_replace("\"", """, $statement);
  13. return $expr 。 -zA-Z0-9_- .x7f-xff]+)]/s", "['\1']", $var));
  14. }
  15. function stripscriptamp($s) {
  16. $s = str_replace ('&', '&', $s);
  17. return "";
  18. }
  19. function stripblock($var, $s) {
  20. $s = str_replace('\"', '"', $s);
  21. $s = preg_replace("/ =\ $(.+?)?>/", "{$\1}", $s);
  22. preg_match_all("/=(.+?)?>/e", $s, $ constary);
  23. $constadd = '';
  24. $constary[1] = array_unique($constary[1]);
  25. foreach($constary[1] as $const) {
  26. $常數.= '$__' 。 $const 。 $ s = str_replace('?>', "n$$var .= $s = str_replace('', "nEOF;n", $s);
  27. 回傳"
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn