讓Web系統的開發與維護更加方便,從而有效的節省人力物力,受到了越來越多企業的青瞇。
模板引擎是MVC模式建立過程的重要方法,開發者可以設計一套賦予含義的標籤,透過技術解析處理有效的把資料邏輯處理從介面模板中提取出來,透過解讀標籤的含義把控制權提交給相應業務邏輯處理程序,從而獲取到需要的數據,以模板設計的形式展現出來,使設計人員能把精力更多放在表現形式上。以下是我對模板引擎的認識與設計方法:
說的好聽些叫模板引擎,實際上就是解讀模板資料的過程(個人觀點^^)。透過我對建站方面的思考認識,網站在展現形式上無非歸納為單條和多條兩種形式,那麼我們可以設定兩種對應標籤(如data、list)來處理這兩種情況,關鍵點在於解決兩種標籤的多層相互嵌套問題,基本上適合實現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 ;
空(標籤::$vars) && 標籤::$vars = &$this->vars;
}
public function LoadTpl($tpl) {
$this->file = $this->GetTplPath($tpl);
標籤::$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'];
return $this->folder.'/'.$tpl;
}
私有函數GetTplHtml() {
$html = self: :FmtTplHtml(file_get_contents($this->file));
if (!empty($html)) {
$callFunc = Tags::$prefix.'語法';
$this->html = 標籤::$callFunc($html, new Template());
} else {
exit('模板檔案內容為空! ');
} 回傳true;
}
靜態公用函數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('模板檔案內容為空!');
}
}
public function 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-> ;電子標誌;
preg_match_all('/'.$rule.'/ism', $this->html, $out_matches);
$this->TransTag($out_matches, '面板');取消設定($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');取消設定($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);
}
} 取消設定($ 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);
}
} 休息;
}
預設:break;
}
} else {
回傳false;
}
}
私有函數RegHatchVars() {
$this->SetPanelTags();
}
函數__destruct() {}
}
?>
複製程式碼程式碼如下:
/*
* 類別:標籤解析類別
* 作者:51JS.COM-ZMM
* 日期:2011.3.2
* 信箱: 304924248 @qq.com
* 部落格:http://www.cnblogs.com/cnzmm/
*/
class Tags {
static private $attrs=null;
static public $file, $vars, $rule, $prefix='TAG_';
靜態公用函數 TAG_Syntax($html, $that) {
$rule = $that->bTag.'ifs+([^'.$that->eFlag.']+)s*'。 ->電子標誌;
$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);
回傳自我::TAG_Execute($html);
}
靜態公用函數 TAG_List($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
返回self::TAG_DealTag($attr, $html, true);
} else {
return self::TAG_GetData($attr, $html, true);
}
} else {
exit('標籤{list}的內容為空!');
}
}
靜態公用函數 TAG_Data($attr, $html) {
if (!empty($html)) {
if (self::TAG_HaveTag($html)) {
回傳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/'。
if ($fp = fopen($file_inc, 'xb')) {
fwrite($fp, $html);
if (fclose($fp)) {
include($file_inc);
$html = ob_get_contents();
} 取消設定($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*'。 ->電子標誌;
$bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html);
取消設定($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);
}
}
}
未設定($tmp_matches);
}
未設定($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 = table_name($source, $column);
$rule = '[字段:s*(w+)s*([^]]*?)s*/?]';
preg_match_all('/'.$rule.'/is', $html, $out_matches);
$data_str = '';
$data_ins = new DataSql();
$attr_where = $attr_order = '';
if (!empty($where)) {
$where = str_replace(',', ' 和 ', $where);
$attr_where = '哪裡'。
} 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 = '從 `'.$source.' 選擇 *'`'。 ;
}
if ($pages=='true' && !empty($size)) {
$data_num = $data_ins->GetRecNum($data_sql);
$page_cnt = ceil( $data_num / $size);
全域$Pages;
if (!isset($page) || $page if ($page > $page_cnt) $page = $page_cnt;
$data_sql = '從`'.$source.'`'.$attr_where中選擇*。 '.$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],
$行[$out_matches[1][$i]], $data_tmp);
}
$data_str .= $data_tmp; $data_idx++;
}
} else {
if (empty($source)) {
exit('標籤{data}必須指定source屬性!');
}
$data_sql = '從 `'.$source 選取 *。
$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 = new 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_ins);
回傳$data_str >} else {
退出; ('標籤設定屬性無效!')
}
} else {
exit('沒有設定標籤屬性!');
static public function __callStatic($name, $args) {
exit('標籤{'.$name.'}不!');
}
}
存在嗎?
以上就介紹了mvc模式 PHP中MVC模式的模板引擎開發經驗分享,包括mvc模式方面的內容,希望對PHP教程有興趣的朋友得到幫助。