ホームページ >バックエンド開発 >PHPチュートリアル >mvc モード PHP での MVC モードのテンプレート エンジン開発経験の共有
Web システムの開発と保守がより便利になり、人的資源と物的資源を効果的に節約できるため、ますます多くの企業に支持されています。
テンプレート エンジンは、MVC パターン確立プロセスにおける重要な方法です。開発者は、意味を与えるタグのセットを設計し、技術的な分析と処理を通じてインターフェイス テンプレートからデータ ロジック処理を効果的に抽出し、インターフェイス テンプレートに制御権限を送信できます。対応するビジネスロジック処理プログラムは、タグの意味を解釈して必要なデータを取得し、テンプレートデザインの形式で表示できるため、設計者は表現形式にさらに集中できます。以下はテンプレートエンジンに対する私の理解と設計方法です:
良く言えばテンプレートエンジンと呼ばれていますが、実際にはテンプレートデータを解釈するプロセスです(個人的な意見です^^)。ウェブサイト構築についての私の考え方と理解により、ウェブサイトの表示形式は 2 つの形式に要約できます: 単一項目と複数項目。次に、これら 2 つの状況に対応する 2 つの対応するタグ (データ、リストなど) を設定できます。ポイントは、2 つのタグの多層ネストの問題を解決し、基本的にインターフェース形式の 80% を実現するのに適していることです。
テンプレートを解釈する方法はたくさんありますが、一般的に使用される方法には、文字列処理 (ネストの解決は少し面倒です) や正規表現が含まれます。ここで選んだ正規表現と、以下が私の処理方法です(この記事はアイデアと参考コードのみを提供するものであり、直接使用することはできません)。
テンプレートファイル解析クラス:
コードをコピー コードは次のとおりです:
/*
* クラス: 模板解析类
* 著者: 51JS.COM-ZMM
* 日付: 2011.3.1
* 電子メール: 304924248@qq.com
* ブログ: http://www .cnblogs.com/cnzmm/
*/
class テンプレート {
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;
}
パブリック関数 LoadTpl($tpl) {
$this->file = $this->GetTplPath($tpl);
Tags::$file = &$this->ファイル;
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);
}
パブリック関数 Register($vars=array()) {
if (is_array($vars)) {
$this->vars = $vars;
Tags::$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->eFlag;
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-> eフラグ。
'((?:(?!'.$this->bTag.')[Ss]*?|(?R))*)'.$this->eTag.'\1s*'.$this ->eフラグ;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, 'トランク'); unset($out_matches);
}
プライベート関数 TransTag($result, $type) {
if (!empty($result[0])) {
switch ($type) {
case 'パネル' : {
for ($i = 0; $i < count($result[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 'トランク' : {
for ($i = 0; $i < count($result[0]); $i ++) {
$callFunc = Tags::$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 {
false を返す;
}
}
プライベート関数 RegHatchVars() {
$this->SetPanelTags();
}
function __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-> ;eフラグ;
$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.'(if|loop)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、真);
} 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 ->eフラグ;
$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
$html = str_ireplace($out_matches[3][$i], '{-->>child_node_'.$i.'<<--}', $html);
}
$html = self::TAG_GetData($attr, $html, $list);
for ($i = 0; $i < count($out_matches[0]); $i ++) {
$html = str_ireplace('{-->>child_node_'.$i.'< <--}'、$child_node[$i]、$html);
}
preg_match_all('/'.self::$rule.'/ism', $html, $tmp_matches);
if (!empty($tmp_matches[0])) {
for ($i = 0; $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 で並べ替えます。
} 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
$row[$out_matches[ 1][$i]]、$data_tmp);
}
$data_str .= $data_tmp; $data_idx ++;
}
} else {
if (empty($source)) {
exit('标签{data} ソースプロパティを指定する必要があります!');
}
$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
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['関数'];
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('标签设置属性無效!')
}
}
}
$data_str .= $data_tmp; ($data_ins);
return $data_str;
} else {
exit('标签设置属性無效!');
exit('没有设置标签属性!'); public function __callStatic($name, $args) {
exit('标签{'.$name.'}存在しません!');
以上は、mvc モードを介した PHP 内の MVC モードのモジュール プレート リリースであり、mvc モードの内容も含まれており、PHP 教則に関心のある友人の助けになることが望まれます。