ホームページ  >  記事  >  バックエンド開発  >  PHP MVC モードでのテンプレート エンジン開発の経験を共有する

PHP MVC モードでのテンプレート エンジン開発の経験を共有する

WBOY
WBOYオリジナル
2016-07-25 09:05:291173ブラウズ
  1. /*
  2. * クラス: 模板解析类
  3. * 著者: 51JS.COM-ZMM
  4. * 日付: 2011.3.1
  5. * 電子メール: 304924248@qq.com
  6. * ブログ: http: //www.cnblogs.com/cnzmm/
  7. * リンク: http://bbs.it-home.org
  8. */
  9. class Template {
  10. public $html, $vars, $bTag, $eTag;
  11. public $bFlag='{', $eFlag='}', $pfix='zmm:';
  12. プライベート $フォルダー、$ファイル;
  13. function __construct($vars=array()) {
  14. !empty($vars) && $this->vars = $vars;
  15. !empty($GLOBALS['cfg_tag_prefix']) &&
  16. $this->pfix = $GLOBALS['cfg_tag_prefix'].':';
  17. $this->bTag = $this->bFlag.$this->pfix;
  18. $this->eTag = $this->bFlag.'/'.$this->pfix;
  19. empty(Tags::$vars) && Tags::$vars = &$this->vars;
  20. }
  21. パブリック関数 LoadTpl($tpl) {
  22. $this->file = $this->GetTplPath($tpl);
  23. Tags::$file = &$this->ファイル;
  24. if (is_file($this->file)) {
  25. if ($this->GetTplHtml()) {
  26. $this->SetTplTags();
  27. } else {
  28. exit('模板文件追加ダウンロード失败!');
  29. }
  30. } else {
  31. exit('模板文件['.$this->file.']存在しません!');
  32. }
  33. }
  34. プライベート関数 GetTplPath($tpl) {
  35. $this->folder = WEBSITE_DIRROOT.
  36. $GLOBALS['cfg_tpl_root'];
  37. $this->folder.'/'.$tpl; を返します。
  38. }
  39. プライベート関数 GetTplHtml() {
  40. $html = self::FmtTplHtml(file_get_contents($this->file));
  41. if (!empty($html)) {
  42. $callFunc = Tags::$prefix.'Syntax';
  43. $this->html = Tags::$callFunc($html, new Template());
  44. } else {
  45. exit('模板文ファイルの内容は空です!');
  46. } true を返します。
  47. }
  48. static public function FmtTplHtml($html) {
  49. return preg_replace('/(r)|(n)|(t)|(s{2,})/is', '', $html);
  50. }
  51. パブリック関数 Register($vars=array()) {
  52. if (is_array($vars)) {
  53. $this->vars = $vars;
  54. Tags::$vars = &$this->vars;
  55. }
  56. }
  57. パブリック関数 Display($bool=false, $name="", $time=0) {
  58. if (!empty($this->html)) {
  59. if ($bool && !empty( $name)) {
  60. if (!is_int($time)) $time = 600;
  61. $cache = 新しいキャッシュ($time);
  62. $cache->Set($name, $this->html);
  63. }
  64. echo $this->html;流す();
  65. } else {
  66. exit('模板文ファイルの内容は空です!');
  67. }
  68. }
  69. パブリック関数 SetAssign($souc, $info) {
  70. if (!empty($this->html)) {
  71. $this->html = str_ireplace($souc, self::FmtTplHtml($ info)、$this->html);
  72. } else {
  73. exit('テンプレートファイルの内容は空です!');
  74. }
  75. }
  76. プライベート関数 SetTplTags() {
  77. $this->SetPanelTags(); $this->SetTrunkTags(); $this->RegHatchVars();
  78. }
  79. プライベート関数 SetPanelTags() {
  80. $rule = $this->bTag.'([^'.$this->eFlag.']+)/'.$this->eFlag;
  81. preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
  82. $this->TransTag($out_matches, 'パネル'); unset($out_matches);
  83. }
  84. プライベート関数 SetTrunkTags() {
  85. $rule = $this->bTag.'(w+)s*([^'.$this->eFlag.']*?)'.$this-> eフラグ。
  86. '((?:(?!'.$this->bTag.')[Ss]*?|(?R))*)'.$this->eTag.'\1s*'.$this ->eフラグ;
  87. preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
  88. $this->TransTag($out_matches, 'トランク'); unset($out_matches);
  89. }
  90. プライベート関数 TransTag($result, $type) {
  91. if (!empty($result[0])) {
  92. switch ($type) {
  93. case 'パネル' : {
  94. for ($i = 0; $i < count($result[0]); $i ++) {
  95. $strTag =explode(' ', $result[1][$i], 2);
  96. if (strpos($strTag[0], '.')) {
  97. $itemArg =explode('.', $result[1][$i], 2);
  98. $callFunc = Tags::$prefix.ucfirst($itemArg[0]);
  99. if (method_exists('Tags', $callFunc)) {
  100. $html = Tags::$callFunc(chop($itemArg[1]));
  101. if ($html !== false) {
  102. $this->html = str_ireplace($result[0][$i], $html, $this->html);
  103. }
  104. }
  105. } else {
  106. $rule = '^([^s]+)s*([Ss]+)$';
  107. preg_match_all('/'.$rule.'/is', trim($result[1][$i]), $tmp_matches);
  108. $callFunc = Tags::$prefix.ucfirst($tmp_matches[1][0]);
  109. if (method_exists('Tags', $callFunc)) {
  110. $html = Tags::$callFunc($tmp_matches[2][0]);
  111. if ($html !== false) {
  112. $this->html = str_ireplace($result[0][$i], $html, $this->html);
  113. }
  114. } unset($tmp_matches);
  115. }
  116. } 休憩;
  117. }
  118. case 'トランク' : {
  119. for ($i = 0; $i < count($result[0]); $i ++) {
  120. $callFunc = Tags::$prefix.ucfirst($result) [1][$i]);
  121. if (method_exists('Tags', $callFunc)) {
  122. $html = Tags::$callFunc($result[2][$i], $result[3][$i]);
  123. $this->html = str_ireplace($result[0][$i], $html, $this->html);
  124. }
  125. } 休憩;
  126. }
  127. デフォルト: ブレーク;
  128. }
  129. } else {
  130. false を返す;
  131. }
  132. }
  133. プライベート関数 RegHatchVars() {
  134. $this->SetPanelTags();
  135. }
  136. function __destruct() {}
  137. }
  138. ?>
复制代

2. タグ解析クラス: (データおよびリストタグの解析アイデアを一時的に提供します)

  1. /*
  2. * クラス: 标签解析类
  3. * 著者: 51JS.COM-ZMM
  4. * 日付: 2011.3.2
  5. * 電子メール: 304924248@qq.com
  6. * ブログ: http: //www.cnblogs.com/cnzmm/
  7. * リンク: http://bbs.it-home.org
  8. */
  9. class タグ {
  10. static private $attrs=null;
  11. static public $file, $vars, $rule, $prefix='TAG_';
  12. static public function TAG_Syntax($html, $that) {
  13. $rule = $that->bTag.'ifs+([^'.$that->eFlag.']+)s*'.$that-> ;eフラグ;
  14. $html = preg_replace('/'.$rule.'/ism', '', $html);
  15. $rule = $that->bTag.'elseifs+([^'.$that->eFlag.']+)s*'.$that->eFlag;
  16. $html = preg_replace('/'.$rule.'/ism', '', $html);
  17. $rule = $that->bTag.'elses*'.$that->eFlag;
  18. $html = preg_replace('/'.$rule.'/ism', '', $html);
  19. $rule = $that->bTag.'loops+(S+)s+(S+)s*'.$that->eFlag;
  20. $html = preg_replace('/'.$rule.'/ism', '', $html);
  21. $rule = $that->bTag.'loops+(S+)s+(S+)s+(S+)s*'.$that->eFlag;
  22. $html = preg_replace('/'.$rule.'/ism', ' \3) { ?>', $html);
  23. $rule = $that->eTag.'(if|loop)s*'.$that->eFlag;
  24. $html = preg_replace('/'.$rule.'/ism', '', $html);
  25. $rule = $that->bTag.'phps*'.$that->eFlag.'((?:(?!'.
  26. $that->bTag.')[Ss]*?|( ?R))*)'.$that->eTag.'phps*'.$that->eFlag;
  27. $html = preg_replace('/'.$rule.'/ism', '', $html);
  28. return self::TAG_Execute($html);
  29. }
  30. 静的パブリック関数 TAG_List($attr, $html) {
  31. if (!empty($html)) {
  32. if (self::TAG_HaveTag($html)) {
  33. return self::TAG_DealTag($attr, $ html、真);
  34. } else {
  35. return self::TAG_GetData($attr, $html, true);
  36. }
  37. } else {
  38. exit('标签{リスト}の内容は空です!');
  39. }
  40. }
  41. 静的パブリック関数 TAG_Data($attr, $html) {
  42. if (!empty($html)) {
  43. if (self::TAG_HaveTag($html)) {
  44. return self::TAG_DealTag($attr) 、$html、false);
  45. } else {
  46. return self::TAG_GetData($attr, $html, false);
  47. }
  48. } else {
  49. exit('标签{data}の内容は空です!');
  50. }
  51. }
  52. 静的パブリック関数 TAG_Execute($html) {
  53. ob_clean(); ob_start();
  54. if (!empty(self::$vars)) {
  55. is_array(self::$vars) &&
  56. extract(self::$vars, EXTR_OVERWRITE);
  57. }
  58. $file_inc = WEBSITE_DIRINC.'/buffer/'。
  59. md5(uniqid(rand(), true)).'.php';
  60. if ($fp = fopen($file_inc, 'xb')) {
  61. fwrite($fp, $html);
  62. if (fclose($fp)) {
  63. include($file_inc);
  64. $html = ob_get_contents();
  65. } unset($fp);
  66. } else {
  67. exit('型板解析文件生成失败!');
  68. } ob_end_clean(); @unlink($file_inc);
  69. $html を返す;
  70. }
  71. 静的プライベート関数 TAG_HaveTag($html) {
  72. $bool_has = false;
  73. $tpl_ins = 新しいテンプレート();
  74. self::$rule = $tpl_ins->bTag.'([^'.$tpl_ins->eFlag.']+)/'.$tpl_ins->eFlag;
  75. $bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html);
  76. self::$rule = $tpl_ins->bTag.'(w+)s*([^'.$tpl_ins->eFlag.']*?)'.$tpl_ins->eFlag.
  77. '((?:(?!'.$tpl_ins->bTag.')[Ss]*?|(?R))*)'.$tpl_ins->eTag.'\1s*'.$tpl_ins ->eフラグ;
  78. $bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html);
  79. unset($tpl_ins);
  80. $bool_has を返す;
  81. }
  82. 静的プライベート関数 TAG_DealTag($attr, $html, $list) {
  83. preg_match_all('/'.self::$rule.'/ism', $html, $out_matches);
  84. if (!empty($out_matches[0])) {
  85. $child_node = array();
  86. for ($i = 0; $i $child_node[] = $out_matches[3][$i];
  87. $html = str_ireplace($out_matches[3][$i], '{-->>child_node_'.$i.'<<--}', $html);
  88. }
  89. $html = self::TAG_GetData($attr, $html, $list);
  90. for ($i = 0; $i < count($out_matches[0]); $i ++) {
  91. $html = str_ireplace('{-->>child_node_'.$i.'< <--}'、$child_node[$i]、$html);
  92. }
  93. preg_match_all('/'.self::$rule.'/ism', $html, $tmp_matches);
  94. if (!empty($tmp_matches[0])) {
  95. for ($i = 0; $i $callFunc = self::$prefix .ucfirst($tmp_matches[1][$i]);
  96. if (method_exists('Tags', $callFunc)) {
  97. $temp = self::$callFunc($tmp_matches[2][$i], $tmp_matches[3][$i]);
  98. $html = str_ireplace($tmp_matches[0][$i], $temp, $html);
  99. }
  100. }
  101. }
  102. unset($tmp_matches);
  103. }
  104. unset($out_matches); $html を返します。
  105. }
  106. 静的プライベート関数 TAG_GetData($attr, $html, $list=false) {
  107. if (!empty($attr)) {
  108. $attr_ins = new Attbt($attr);
  109. $attr_arr = $attr_ins->attrs;
  110. if (is_array($attr_arr)) {
  111. extract($attr_arr, EXTR_OVERWRITE);
  112. $source = テーブル名($source, $column);
  113. $rule = '[フィールド:s*(w+)s*([^]]*?)s*/?]';
  114. preg_match_all('/'.$rule.'/is', $html, $out_matches);
  115. $data_str = '';
  116. $data_ins = 新しい DataSql();
  117. $attr_where = $attr_order = '';
  118. if (!empty($where)) {
  119. $where = str_replace(',', ' and ', $where);
  120. $attr_where = 'どこ'。 $どこ;
  121. }
  122. if (!empty($order)) {
  123. $attr_order = ' '.$order で並べ替えます。
  124. } else {
  125. $fed_name = '';
  126. $fed_ins = $data_ins->GetFedNeedle($source);
  127. $fed_cnt = $data_ins->GetFedCount($fed_ins);
  128. for ($i = 0; $i $fed_flag = $data_ins->GetFedFlag($fed_ins, $i);
  129. if (preg_match('/auto_increment/ism', $fed_flag)) {
  130. $fed_name = $data_ins->GetFedName($fed_ins, $i);
  131. 休憩;
  132. }
  133. }
  134. if (!empty($fed_name))
  135. $attr_order = ' '.$fed_name' で注文します。説明';
  136. }
  137. if ($list == true) {
  138. if (empty($source) && empty($sql)) {
  139. exit('标签{list}必ずソースプロパティを指定してください!');
  140. }
  141. $attr_rows = $attr_page = '';
  142. if ($rows > 0) {
  143. $attr_rows = ' 制限 0,'.$rows;
  144. }
  145. if (!empty($sql)) {
  146. $data_sql = $sql;
  147. } else {
  148. $data_sql = 'select * from `'.$source.'`'。
  149. $attr_where.$attr_order.$attr_rows;
  150. }
  151. if ($pages=='true' && !empty($size)) {
  152. $data_num = $data_ins->GetRecNum($data_sql);
  153. $page_cnt = ceil($data_num / $size);
  154. グローバル $ページ;
  155. if (!isset($page) || $page if ($page > $page_cnt) $page = $page_cnt;
  156. $data_sql = 'select * from `'.$source.'`'.$attr_where.
  157. $attr_order.'制限 '.($page-1) * $size.','.$size;
  158. $GLOBALS['cfg_page_curr'] = $page;
  159. $GLOBALS['cfg_page_prev'] = $page - 1;
  160. $GLOBALS['cfg_page_next'] = $page + 1;
  161. $GLOBALS['cfg_page_nums'] = $page_cnt;
  162. if (function_exists('list_pagelink')) {
  163. $GLOBALS['cfg_page_list'] = list_pagelink($page, $page_cnt, 2);
  164. }
  165. }
  166. $data_idx = 0;
  167. $data_ret = $data_ins->SqlCmdExec($data_sql);
  168. while ($row = $data_ins->GetRecArr($data_ret)) {
  169. if ($skip > 0 && !empty($flag)) {
  170. $data_idx != 0 &&
  171. $data_idx % $skip == 0 &&
  172. $data_str .= $flag;
  173. }
  174. $data_tmp = $html;
  175. $data_tmp = str_ireplace('@idx', $data_idx, $data_tmp);
  176. for ($i = 0; $i $data_tmp = str_ireplace($out_matches[0][$i],
  177. $row[$out_matches[ 1][$i]]、$data_tmp);
  178. }
  179. $data_str .= $data_tmp; $data_idx ++;
  180. }
  181. } else {
  182. if (empty($source)) {
  183. exit('标签{data} ソースプロパティを指定する必要があります!');
  184. }
  185. $data_sql = 'select * from `'.$source.
  186. '`'.$attr_where.$attr_order;
  187. $row = $data_ins->GetOneRec($data_sql);
  188. if (is_array($row)) {
  189. $data_tmp = $html;
  190. for ($i = 0; $i $data_val = $row[$out_matches[1][$i]];
  191. if (empty($out_matches[2][$i])) {
  192. $data_tmp = str_ireplace($out_matches[0][$i], $data_val, $data_tmp);
  193. } else {
  194. $attr_str = $out_matches[2][$i];
  195. $attr_ins = 新しい Attbt($attr_str);
  196. $func_txt = $attr_ins->attrs['関数'];
  197. if (!empty($func_txt)) {
  198. $func_tmp =explode('(', $func_txt);
  199. if (function_exists($func_tmp[0])) {
  200. eval('$func_ret ='.str_ireplace(') @me',
  201. '''.$data_val.''', $func_txt));
  202. $data_tmp = str_ireplace($out_matches[0][$i], $func_ret, $data_tmp); ('调用了存在しない関数数!');
  203. }
  204. } else {
  205. exit('标签设置属性無效!')
  206. }
  207. }
  208. }
  209. $data_str .= $data_tmp; ($data_ins);
  210. return $data_str;
  211. } else {
  212. exit('标签设置属性無效!');
  213. exit('没有设置标签属性!'); public function __callStatic($name, $args) {
  214. exit('标签{'.$name.'}存在しません!')
  215. }
  216. }
  217. ?>
  218. 复制代
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。