Discuz的模板引擎

Jul 25, 2016 am 09:06 AM

填写您的邮件地址,订阅我们的精彩内容:

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. *
  18. * @var array
  19. */
  20. protected $_options = array();
  21. /**
  22. * 单件模式调用方法
  23. *
  24. * @static
  25. * @return object Template
  26. */
  27. public static function getInstance() {
  28. if (!self :: $_instance instanceof self)
  29. self :: $_instance = new self();
  30. return self :: $_instance;
  31. }
  32. /**
  33. * 构造方法
  34. *
  35. * @return void
  36. */
  37. private function __construct() {
  38. $this -> _options = array('template_dir' => 'templates' . self :: DIR_SEP, // 模板文件所在目录
  39. 'cache_dir' => 'templates' . self :: DIR_SEP . 'cache' . self :: DIR_SEP, // 缓存文件存放目录
  40. 'auto_update' => false, // 当模板文件改动时是否重新生成缓存
  41. 'cache_lifetime' => 0, // 缓存生命周期(分钟),为 0 表示永久
  42. );
  43. }
  44. /**
  45. * 设定模板参数信息
  46. *
  47. * @param array $options 参数数组
  48. * @return void
  49. */
  50. public function setOptions(array $options) {
  51. foreach ($options as $name => $value)
  52. $this -> set($name, $value);
  53. }
  54. /**
  55. * 设定模板参数
  56. *
  57. * @param string $name 参数名称
  58. * @param mixed $value 参数值
  59. * @return void
  60. */
  61. public function set($name, $value) {
  62. switch ($name) {
  63. case 'template_dir':
  64. $value = $this -> _trimpath($value);
  65. if (!file_exists($value))
  66. $this -> _throwException("未找到指定的模板目录 \"$value\"");
  67. $this -> _options['template_dir'] = $value;
  68. break;
  69. case 'cache_dir':
  70. $value = $this -> _trimpath($value);
  71. if (!file_exists($value))
  72. $this -> _throwException("未找到指定的缓存目录 \"$value\"");
  73. $this -> _options['cache_dir'] = $value;
  74. break;
  75. case 'auto_update':
  76. $this -> _options['auto_update'] = (boolean) $value;
  77. break;
  78. case 'cache_lifetime':
  79. $this -> _options['cache_lifetime'] = (float) $value;
  80. break;
  81. default:
  82. $this -> _throwException("未知的模板配置选项 \"$name\"");
  83. }
  84. }
  85. /**
  86. * 通过魔术方法设定模板参数
  87. *
  88. * @see Template::set()
  89. * @param string $name 参数名称
  90. * @param mixed $value 参数值
  91. * @return void
  92. */
  93. public function __set($name, $value) {
  94. $this -> set($name, $value);
  95. }
  96. /**
  97. * 获取模板文件
  98. *
  99. * @param string $file 模板文件名称
  100. * @return string
  101. */
  102. public function getfile($file) {
  103. $cachefile = $this -> _getCacheFile($file);
  104. if (!file_exists($cachefile))
  105. $this -> cache($file);
  106. return $cachefile;
  107. }
  108. /**
  109. * 检测模板文件是否需要更新缓存
  110. *
  111. * @param string $file 模板文件名称
  112. * @param string $md5data 模板文件 md5 校验信息
  113. * @param integer $md5data 模板文件到期时间校验信息
  114. * @return void
  115. */
  116. public function check($file, $md5data, $expireTime) {
  117. if ($this -> _options['auto_update'] && md5_file($this -> _getTplFile($file)) != $md5data)
  118. $this -> cache($file);
  119. if ($this -> _options['cache_lifetime'] != 0 && (time() - $expireTime >= $this -> _options['cache_lifetime'] * 60))
  120. $this -> cache($file);
  121. }
  122. /**
  123. * 对模板文件进行缓存
  124. *
  125. * @param string $file 模板文件名称
  126. * @return void
  127. */
  128. public function cache($file) {
  129. $tplfile = $this -> _getTplFile($file);
  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("/\{lang\s+(.+?)\}/ies", "languagevar('\\1')", $template);
  139. // 替换 PHP 换行符
  140. $template = str_replace("{LF}", "=\"\\n\"?>", $template);
  141. // 替换直接变量输出
  142. $varRegexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)"
  143. . "(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
  144. $template = preg_replace("/\{(\\\$[a-zA-Z0-9_\[\]\'\"\$\.\x7f-\xff]+)\}/s", "=\\1?>", $template);
  145. $template = preg_replace("/$varRegexp/es", "addquote('=\\1?>')", $template);
  146. $template = preg_replace("/\\?\>/es", "addquote('=\\1?>')", $template);
  147. // 替换模板载入命令
  148. $template = preg_replace("/[\n\r\t]*\{template\s+([a-z0-9_]+)\}[\n\r\t]*/is",
  149. "\r\n include(\$template->getfile('\\1')); ?>\r\n",
  150. $template
  151. );
  152. $template = preg_replace("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/is",
  153. "\r\n include(\$template->getfile(\\1)); ?>\r\n",
  154. $template
  155. );
  156. // 替换特定函数
  157. $template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\}[\n\r\t]*/ies",
  158. "stripvtags(' \\1 ?>','')",
  159. $template
  160. );
  161. $template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies",
  162. "stripvtags(' echo \\1; ?>','')",
  163. $template
  164. );
  165. $template = preg_replace("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies",
  166. "stripvtags('\\1 } elseif(\\2) { ?>\\3','')",
  167. $template
  168. );
  169. $template = preg_replace("/([\n\r\t]*)\{else\}([\n\r\t]*)/is",
  170. "\\1 } else { ?>\\2",
  171. $template
  172. );
  173. // 替换循环函数及条件判断语句
  174. $nest = 5;
  175. for ($i = 0; $i $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r]*(.+?)[\n\r]*\{\/loop\}[\n\r\t]*/ies",
  176. "stripvtags(' if(is_array(\\1)) { foreach(\\1 as \\2) { ?>','\\3 } } ?>')",
  177. $template
  178. );
  179. $template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*(.+?)[\n\r\t]*\{\/loop\}[\n\r\t]*/ies",
  180. "stripvtags(' if(is_array(\\1)) { foreach(\\1 as \\2 => \\3) { ?>','\\4 } } ?>')",
  181. $template
  182. );
  183. $template = preg_replace("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r]*)(.+?)([\n\r]*)\{\/if\}([\n\r\t]*)/ies",
  184. "stripvtags('\\1 if(\\2) { ?>\\3','\\4\\5 } ?>\\6')",
  185. $template
  186. );
  187. }
  188. // 常量替换
  189. $template = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/s",
  190. "=\\1?>",
  191. $template
  192. );
  193. // 删除 PHP 代码断间多余的空格及换行
  194. $template = preg_replace("/ \?\>[\n\r]*\ // 其他替换
  195. $template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e",
  196. "transamp('\\0')",
  197. $template
  198. );
  199. $template = preg_replace("/\<script>]*?src=\"(.+?)\".*?\>\s*\<\/script\>/ise",<li> "stripscriptamp('\\1')",<li> $template<li> );<li> $template = preg_replace("/[\n\r\t]*\{block\s+([a-zA-Z0-9_]+)\}(.+?)\{\/block\}/ies",<li> "stripblock('\\1', '\\2')",<li> $template<li> ); <li> // 添加 md5 及过期校验<li> $md5data = md5_file($tplfile);<li> $expireTime = time();<li> $template = "<? if (!class_exists('template')) die('Access Denied');"<li> . "\$template->getInstance()->check('$file', '$md5data', $expireTime);"<li> . "?>\r\n$template"; <li> // 写入缓存文件<li> $cachefile = $this -> _getCacheFile($file);<li> $makepath = $this -> _makepath($cachefile);<li> if ($makepath !== true)<li> $this -> _throwException("无法创建缓存目录 \"$makepath\"");<li> file_put_contents($cachefile, $template);<li> } <li><li> /**<li> * 将路径修正为适合操作系统的形式<li> * <li> * @param string $path 路径名称<li> * @return string <li> */<li> protected function _trimpath($path) {<li> return str_replace(array('/', '\\', '//', '\\\\'), self :: DIR_SEP, $path);<li> } <li><li> /**<li> * 获取模板文件名及路径<li> * <li> * @param string $file 模板文件名称<li> * @return string <li> */<li> protected function _getTplFile($file) {<li> return $this -> _trimpath($this -> _options['template_dir'] . self :: DIR_SEP . $file);<li> } <li><li> /**<li> * 获取模板缓存文件名及路径<li> * <li> * @param string $file 模板文件名称<li> * @return string <li> */<li> protected function _getCacheFile($file) {<li> $file = preg_replace('/\.[a-z0-9\-_]+$/i', '.cache.php', $file);<li> return $this -> _trimpath($this -> _options['cache_dir'] . self :: DIR_SEP . $file);<li> } <li><li> /**<li> * 根据指定的路径创建不存在的文件夹<li> * <li> * @param string $path 路径/文件夹名称<li> * @return string <li> */<li> protected function _makepath($path) {<li> $dirs = explode(self :: DIR_SEP, dirname($this -> _trimpath($path)));<li> $tmp = '';<li> foreach ($dirs as $dir) {<li> $tmp .= $dir . self :: DIR_SEP;<li> if (!file_exists($tmp) && !@mkdir($tmp, 0777))<li> return $tmp;<li> } <li> return true;<li> } <li><li> /**<li> * 抛出一个错误信息<li> * <li> * @param string $message <li> * @return void <li> */<li> protected function _throwException($message) {<li> throw new Exception($message);<li> } <li>} <li><li>?><li><li></script>
复制代码
  1. 模板函数文件
  2. /**
  3. * 模板替换中需要用到的函数
  4. * http://blog.qita.in
  5. */
  6. function transamp($template) {
  7. $template = str_replace('&', '&', $template);
  8. $template = str_replace('&', '&', $template);
  9. $template = str_replace('\"', '"', $template);
  10. return $template;
  11. }
  12. function stripvtags($expr, $statement) {
  13. $expr = str_replace("\\\"", "\"", preg_replace("/\/s", "\\1", $expr));
  14. $statement = str_replace("\\\"", "\"", $statement);
  15. return $expr . $statement;
  16. }
  17. function addquote($var) {
  18. return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
  19. }
  20. function stripscriptamp($s) {
  21. $s = str_replace('&', '&', $s);
  22. return "";
  23. }
  24. function stripblock($var, $s) {
  25. $s = str_replace('\\"', '"', $s);
  26. $s = preg_replace("//", "{\$\\1}", $s);
  27. preg_match_all("//e", $s, $constary);
  28. $constadd = '';
  29. $constary[1] = array_unique($constary[1]);
  30. foreach($constary[1] as $const) {
  31. $constadd .= '$__' . $const .' = ' . $const . ';';
  32. }
  33. $s = preg_replace("//", "{\$__\\1}", $s);
  34. $s = str_replace('?>', "\n\$$var .= $s = str_replace('', "\nEOF;\n", $s);
  35. return "\n$constadd\$$var = ";
  36. }
  37. ?>
复制代码


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Jelaskan JSON Web Tokens (JWT) dan kes penggunaannya dalam PHP API. Jelaskan JSON Web Tokens (JWT) dan kes penggunaannya dalam PHP API. Apr 05, 2025 am 12:04 AM

JWT adalah standard terbuka berdasarkan JSON, yang digunakan untuk menghantar maklumat secara selamat antara pihak, terutamanya untuk pengesahan identiti dan pertukaran maklumat. 1. JWT terdiri daripada tiga bahagian: header, muatan dan tandatangan. 2. Prinsip kerja JWT termasuk tiga langkah: menjana JWT, mengesahkan JWT dan muatan parsing. 3. Apabila menggunakan JWT untuk pengesahan di PHP, JWT boleh dijana dan disahkan, dan peranan pengguna dan maklumat kebenaran boleh dimasukkan dalam penggunaan lanjutan. 4. Kesilapan umum termasuk kegagalan pengesahan tandatangan, tamat tempoh, dan muatan besar. Kemahiran penyahpepijatan termasuk menggunakan alat debugging dan pembalakan. 5. Pengoptimuman prestasi dan amalan terbaik termasuk menggunakan algoritma tandatangan yang sesuai, menetapkan tempoh kesahihan dengan munasabah,

Bagaimanakah sesi merampas kerja dan bagaimana anda dapat mengurangkannya dalam PHP? Bagaimanakah sesi merampas kerja dan bagaimana anda dapat mengurangkannya dalam PHP? Apr 06, 2025 am 12:02 AM

Sesi rampasan boleh dicapai melalui langkah -langkah berikut: 1. Dapatkan ID Sesi, 2. Gunakan ID Sesi, 3. Simpan sesi aktif. Kaedah untuk mengelakkan rampasan sesi dalam PHP termasuk: 1. Gunakan fungsi Sesi_Regenerate_ID () untuk menjana semula ID Sesi, 2. Data sesi stor melalui pangkalan data, 3.

Huraikan prinsip -prinsip yang kukuh dan bagaimana ia memohon kepada pembangunan PHP. Huraikan prinsip -prinsip yang kukuh dan bagaimana ia memohon kepada pembangunan PHP. Apr 03, 2025 am 12:04 AM

Penerapan prinsip pepejal dalam pembangunan PHP termasuk: 1. Prinsip Tanggungjawab Tunggal (SRP): Setiap kelas bertanggungjawab untuk hanya satu fungsi. 2. Prinsip Terbuka dan Tutup (OCP): Perubahan dicapai melalui lanjutan dan bukannya pengubahsuaian. 3. Prinsip Penggantian Lisch (LSP): Subkelas boleh menggantikan kelas asas tanpa menjejaskan ketepatan program. 4. Prinsip Pengasingan Antara Muka (ISP): Gunakan antara muka halus untuk mengelakkan kebergantungan dan kaedah yang tidak digunakan. 5. Prinsip Inversi Ketergantungan (DIP): Modul peringkat tinggi dan rendah bergantung kepada abstraksi dan dilaksanakan melalui suntikan ketergantungan.

Bagaimana cara debug mod CLI dalam phpstorm? Bagaimana cara debug mod CLI dalam phpstorm? Apr 01, 2025 pm 02:57 PM

Bagaimana cara debug mod CLI dalam phpstorm? Semasa membangun dengan PHPStorm, kadang -kadang kita perlu debug PHP dalam mod Interface Line Command (CLI) ...

Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Bagaimana cara menetapkan kebenaran secara automatik UnixSocket selepas sistem dimulakan semula? Mar 31, 2025 pm 11:54 PM

Bagaimana untuk menetapkan keizinan UnixSocket secara automatik selepas sistem dimulakan semula. Setiap kali sistem dimulakan semula, kita perlu melaksanakan perintah berikut untuk mengubahsuai keizinan UnixSocket: sudo ...

Terangkan pengikatan statik lewat dalam php (statik: :). Terangkan pengikatan statik lewat dalam php (statik: :). Apr 03, 2025 am 12:04 AM

Mengikat statik (statik: :) Melaksanakan pengikatan statik lewat (LSB) dalam PHP, yang membolehkan kelas panggilan dirujuk dalam konteks statik dan bukannya menentukan kelas. 1) Proses parsing dilakukan pada masa runtime, 2) Cari kelas panggilan dalam hubungan warisan, 3) ia boleh membawa overhead prestasi.

Bagaimana cara menghantar permintaan pos yang mengandungi data JSON menggunakan perpustakaan php curl? Bagaimana cara menghantar permintaan pos yang mengandungi data JSON menggunakan perpustakaan php curl? Apr 01, 2025 pm 03:12 PM

Menghantar data JSON menggunakan perpustakaan Curl PHP dalam pembangunan PHP, sering kali perlu berinteraksi dengan API luaran. Salah satu cara biasa ialah menggunakan perpustakaan curl untuk menghantar post ...

See all articles