検索
ホームページphp教程php手册PHP の MVC モードでのテンプレート エンジン開発の経験を共有する

Web システムの開発と保守がより便利になり、人的資源と物的資源を効果的に節約できるため、ますます多くの企業に支持されています。

テンプレート エンジンは、MVC パターン確立プロセスにおける重要な方法であり、開発者は意味を与えるタグのセットを設計し、技術的な分析と意味の解釈を通じてインターフェイス テンプレートからデータ ロジック処理を効果的に抽出できます。タグの制御権を対応するビジネス ロジック処理プログラムに送信して、必要なデータを取得し、テンプレート デザインの形式で表示することで、デザイナーは表現形式にさらに集中できます。以下はテンプレートエンジンに対する私の理解と設計方法です:

良く言えばテンプレートエンジンといいますが、実際にはテンプレートデータを解釈する処理です(個人の意見^^)。ウェブサイト構築についての私の考え方と理解により、ウェブサイトの表示形式は 2 つの形式に要約できます: 単一項目と複数項目。次に、これら 2 つの状況に対応する 2 つの対応するタグ (データ、リストなど) を設定できます。ポイントは、2 つのタグの多層ネストの問題を解決し、基本的にインターフェース形式の 80% を実現するのに適していることです。

テンプレートを解釈する方法はたくさんありますが、一般的に使用される方法には、文字列処理 (ネストの解決は少し面倒です) と正規表現が含まれます。ここで選んだ正規表現と、以下が私の処理方法です(この記事はアイデアと参考コードのみを提供するものであり、直接使用することはできません)。

テンプレート ファイル解析クラス:

コードをコピー コードは次のとおりです:


/*
* クラス: 模板解析类
* 著者: 51JS.COM-ZMM
* 日付: 2011.3.1
* 電子メール: 304924248@qq .com
* ブログ: http://www.cnblogs.com/cnzmm/
*/
class Template {
public $html, $vars, $bTag, $eTag;
public $bFlag='{', $eFlag='}', $pfix='zmm:';
プライベート $フォルダー、$ファイル;
function __construct($vars=array()) {
!empty($vars) && $this->vars = $vars;
!empty($GLOBALS['cfg_tag_prefix']) &&
$this->pfix = $GLOBALS['cfg_tag_prefix'].':';
$this->bTag = $this->bFlag.$this->pfix;
$this->eTag = $this->bFlag.'/'.$this->pfix;
empty(Tags::$vars) && Tags::$vars = &$this->vars;
}
public function LoadTpl($tpl) {
$this->file = $this->GetTplPath($tpl);
Tags::$file = &$this->file;
if (is_file($this->file)) {
if ($this->GetTplHtml()) {
$this->SetTplTags();
} else {
exit('模板文件追加失败!');
}
} else {
exit('模板文件['.$this->file.']存在しません!');
}
}
プライベート関数 GetTplPath($tpl) {
$this->folder = WEBSITE_DIRROOT.
$GLOBALS['cfg_tpl_root'];
$this->folder を返します。'/'.$tpl;
}
プライベート関数 GetTplHtml() {
$html = self::FmtTplHtml(file_get_contents($this->file));
if (!empty($html)) {
$callFunc = Tags::$prefix.'Syntax';
$this->html = Tags::$callFunc($html, new Template());
} else {
exit('型板文書の内容は空です!');
} true を返します。
}
static public function FmtTplHtml($html) {
return preg_replace('/(r)(n)(t)(s{2,})/is', '', $html) ;
}
public function Register($vars=array()) {
if (is_array($vars)) {
$this->vars = $vars;
タグ::$vars = &$this->vars;
}
}
パブリック関数 Display($bool=false, $name="", $time=0) {
if (!empty($this->html)) {
if ($bool && !empty($name)) {
if (!is_int($time)) $time = 600;
$cache = 新しいキャッシュ($time);
$cache->Set($name, $this->html);
}
echo $this->html;フラッシュ();
} else {
exit('型板文書の内容は空です!');
}
}
パブリック関数 SetAssign($souc, $info) {
if (!empty($this->html)) {
$this->html = str_ireplace ($souc, self::FmtTplHtml($info), $this->html);
} else {
exit('型板文書の内容は空です!');
}
}
プライベート関数 SetTplTags() {
$this->SetPanelTags(); $this->SetTrunkTags(); $this->RegHatchVars();
}
プライベート関数 SetPanelTags() {
$rule = $this->bTag.'([^'.$this->eFlag.']+)/'.$this-> ;eフラグ;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, 'パネル'); unset($out_matches);
}
プライベート関数 SetTrunkTags() {
$rule = $this->bTag.'(w+)s*([^'.$this->eFlag.']*?)' .$this->eFlag。
'((?:(?!'.$this->bTag.')[Ss]*?(?R))*)'.$this->eTag.'\1s*'.$ this->eFlag;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, 'trunk'); unset($out_matches);
}
プライベート関数 TransTag($result, $type) {
if (!empty($result[0])) {
switch ($type) {
case 'パネル' : {
for ($i = 0; $i $strTag =explode(' ', $result[1][$i ]、2);
if (strpos($strTag[0], '.')) {
$itemArg =explode('.', $result[1][$i], 2);
$callFunc = Tags::$prefix.ucfirst($itemArg[0]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc(chop($itemArg[1]));
if ($html !== false) {
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
}
} else {
$rule = '^([^s]+)s*([Ss]+)$';
preg_match_all('/'.$rule.'/is', trim($result[1][$i]), $tmp_matches);
$callFunc = Tags::$prefix.ucfirst($tmp_matches[1][0]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc($tmp_matches[2][0]);
if ($html !== false) {
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
} unset($tmp_matches);
}
} 休憩;
}
case 'trunk' : {
for ($i = 0; $i $callFunc = タグ: :$prefix.ucfirst($result[1][$i]);
if (method_exists('Tags', $callFunc)) {
$html = Tags::$callFunc($result[2][$i], $result[3][$i]);
$this->html = str_ireplace($result[0][$i], $html, $this->html);
}
} 休憩;
}
デフォルト: ブレーク;
}
} else {
return false;
}
}
プライベート関数 RegHatchVars() {
$this->SetPanelTags();
}
関数 __destruct() {}
}
?>


タグ解析クラス: (現在、アイデアを説明するためにデータとリスト タグの解析を提供しています)

コードをコピー コードは次のとおりです:


/*
* クラス: 标签解析类
* 著者: 51JS.COM-ZMM
* 日付: 2011.3.2
* 電子メール: 304924248@qq .com
* ブログ: http://www.cnblogs.com/cnzmm/
*/
class タグ {
static private $attrs=null;
static public $file, $vars, $rule, $prefix='TAG_';
static public function TAG_Syntax($html, $that) {
$rule = $that->bTag.'ifs+([^'.$that->eFlag.']+)s*'. $that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'elseifs+([^'.$that->eFlag.']+)s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'elses*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'loops+(S+)s+(S+)s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'loops+(S+)s+(S+)s+(S+)s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', ' \3) { ?>', $html);
$rule = $that->eTag.'(ifloop)s*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
$rule = $that->bTag.'phps*'.$that->eFlag.'((?:(?!'.
$that->bTag.')[Ss] *?(?R))*)'.$that->eTag.'phps*'.$that->eFlag;
$html = preg_replace('/'.$rule.'/ism', '', $html);
return self::TAG_Execute($html);
}
静的パブリック関数 TAG_List($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
return self::TAG_DealTag($attr, $html, true);
} else {
return self::TAG_GetData($attr, $html, true);
}
} else {
exit('标签{リスト}の内容は空です!');
}
}
静的パブリック関数 TAG_Data($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
return self::TAG_DealTag($attr, $html, false);
} else {
return self::TAG_GetData($attr, $html, false);
}
} else {
exit('标签{data}の内容は空です!');
}
}
静的パブリック関数 TAG_Execute($html) {
ob_clean(); ob_start();
if (!empty(self::$vars)) {
is_array(self::$vars) &&
extract(self::$vars, EXTR_OVERWRITE);
}
$file_inc = WEBSITE_DIRINC.'/buffer/'。
md5(uniqid(rand(), true)).'.php';
if ($fp = fopen($file_inc, 'xb')) {
fwrite($fp, $html);
if (fclose($fp)) {
include($file_inc);
$html = ob_get_contents();
} unset($fp);
} else {
exit('型板文件生成失败!');
} ob_end_clean(); @unlink($file_inc);
$html を返す;
}
静的プライベート関数 TAG_HaveTag($html) {
$bool_has = false;
$tpl_ins = 新しいテンプレート();
self::$rule = $tpl_ins->bTag.'([^'.$tpl_ins->eFlag.']+)/'.$tpl_ins->eFlag;
$bool_has = $bool_has preg_match('/'.self::$rule.'/ism', $html);
self::$rule = $tpl_ins->bTag.'(w+)s*([^'.$tpl_ins->eFlag.']*?)'.$tpl_ins->eFlag.
'((?:(?!'.$tpl_ins->bTag.')[Ss]*?(?R))*)'.$tpl_ins->eTag.'\1s*'.$ tpl_ins->eFlag;
$bool_has = $bool_has preg_match('/'.self::$rule.'/ism', $html);
unset($tpl_ins);
$bool_has を返す;
}
静的プライベート関数 TAG_DealTag($attr, $html, $list) {
preg_match_all('/'.self::$rule.'/ism', $html, $out_matches);
if (!empty($out_matches[0])) {
$child_node = array();
for ($i = 0; $i $child_node[] = $out_matches[3][$i];
$html = str_ireplace($out_matches[3][$i], '{-->>child_node_'.$i.'}
$html = self::TAG_GetData($attr, $html, $list);
for ($i = 0; $i $html = str_ireplace('{-->>child_node_'.$i .'}
preg_match_all('/'.self::$rule.'/ism', $html, $tmp_matches);
if (!empty($tmp_matches[0])) {
for ($i = 0; $i $callFunc = self::$prefix.ucfirst($tmp_matches[1][$i]);
if (method_exists('Tags', $callFunc)) {
$temp = self::$callFunc($tmp_matches[2][$i], $tmp_matches[3][$i]);
$html = str_ireplace($tmp_matches[0][$i], $temp, $html);
}
}
}
unset($tmp_matches);
}
unset($out_matches); $html を返します。
}
静的プライベート関数 TAG_GetData($attr, $html, $list=false) {
if (!empty($attr)) {
$attr_ins = new Attbt($attr);
$attr_arr = $attr_ins->attrs;
if (is_array($attr_arr)) {
extract($attr_arr, EXTR_OVERWRITE);
$source = テーブル名($source, $column);
$rule = '[フィールド:s*(w+)s*([^]]*?)s*/?]';
preg_match_all('/'.$rule.'/is', $html, $out_matches);
$data_str = '';
$data_ins = 新しい DataSql();
$attr_where = $attr_order = '';
if (!empty($where)) {
$where = str_replace(',', ' and ', $where);
$attr_where = 'どこ'。 $どこ;
}
if (!empty($order)) {
$attr_order = ' order by '.$order;
} else {
$fed_name = '';
$fed_ins = $data_ins->GetFedNeedle($source);
$fed_cnt = $data_ins->GetFedCount($fed_ins);
for ($i = 0; $i $fed_flag = $data_ins->GetFedFlag($fed_ins, $i);
if (preg_match('/auto_increment/ism', $fed_flag)) {
$fed_name = $data_ins->GetFedName($fed_ins, $i);
休憩;
}
}
if (!empty($fed_name))
$attr_order = ' '.$fed_name.' で並べ替えます。説明';
}
if ($list == true) {
if (empty($source) && empty($sql)) {
exit('标签{list}はソースプロパティを指定する必要があります!' );
}
$attr_rows = $attr_page = '';
if ($rows > 0) {
$attr_rows = ' 制限 0,'.$rows;
}
if (!empty($sql)) {
$data_sql = $sql;
} else {
$data_sql = 'select * from `'.$source.'`'。
$attr_where.$attr_order.$attr_rows;
}
if ($pages=='true' && !empty($size)) {
$data_num = $data_ins->GetRecNum($data_sql);
$page_cnt = ceil($data_num / $size);
グローバル $ページ;
if (!isset($page) $page if ($page > $page_cnt) $page = $page_cnt;
$data_sql = 'select * from `'.$source.'`'.$attr_where.
$attr_order.'制限 '.($page-1) * $size.','.$size;
$GLOBALS['cfg_page_curr'] = $page;
$GLOBALS['cfg_page_prev'] = $page - 1;
$GLOBALS['cfg_page_next'] = $page + 1;
$GLOBALS['cfg_page_nums'] = $page_cnt;
if (function_exists('list_pagelink')) {
$GLOBALS['cfg_page_list'] = list_pagelink($page, $page_cnt, 2);
}
}
$data_idx = 0;
$data_ret = $data_ins->SqlCmdExec($data_sql);
while ($row = $data_ins->GetRecArr($data_ret)) {
if ($skip > 0 && !empty($flag)) {
$data_idx != 0 &&
$data_idx % $skip == 0 &&
$data_str .= $flag;
}
$data_tmp = $html;
$data_tmp = str_ireplace('@idx', $data_idx, $data_tmp);
for ($i = 0; $i $data_tmp = str_ireplace($out_matches[0][$i],
$row[$out_matches[1][$i]], $data_tmp);
}
$data_str .= $data_tmp; $data_idx ++;
}
} else {
if (empty($source)) {
exit('标签{データ}はソースプロパティを指定する必要があります!');
}
$data_sql = 'select * from `'.$source.
'`'.$attr_where.$attr_order;
$row = $data_ins->GetOneRec($data_sql);
if (is_array($row)) {
$data_tmp = $html;
for ($i = 0; $i $data_val = $row[$out_matches[1][$i]];
if (empty($out_matches[2][$i])) {
$data_tmp = str_ireplace($out_matches[0][$i], $data_val, $data_tmp);
} else {
$attr_str = $out_matches[2][$i];
$attr_ins = 新しい Attbt($attr_str);
$func_txt = $attr_ins->attrs['function'];
if (!empty($func_txt)) {
$func_tmp =explode('(', $func_txt);
if (function_exists($func_tmp[0])) {
eval(' $func_ret ='.str_ireplace('@me',
'''.$data_val.''', $func_txt));
$data_tmp = str_ireplace($out_matches[0][$i], $ func_ret, $data_tmp);
} else {
exit('调用了不存在関数数!')
}
} else {
exit('标签设置属性無效!' );
}
}
$data_str .= $data_tmp;
}
return $data_str; >} else {
exit('标签设置属性無效!');
}
} else {
exit('没有设置属性無效!');
static public function __callStatic($name, $args) {
exit('标签{'.$name.'}存在しません!');
}
}
?>






声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター