模板引擎是mvc模式建立过程的重要方法,开发者可以设计一套赋予含义的标签,通过技术解析处理有效的把数据逻辑处理从界面模板中提取出来,通过解读标签的含义把控制权提交给相应业务逻辑处理程序,从而获取到需要的数据,以模板设计的形式展现出来,使设计人员能把精力更多放在表现形式上。下面是我对模板引擎的认识与设计方法:
说的好听些叫模板引擎,实际就是解读模板数据的过程(个人观点^^)。通过我对建站方面的思考认识,网站在展现形式上无非归纳为单条和多条两种形式,那么我们可以设定两种对应标签(如data、list)来处理这两种情况,关键点在于解决两种标签的多层相互嵌套问题,基本适合实现80%界面形式。
解读模板的方法有多种,常用的包括字符串处理(解决嵌套稍麻烦)、正则表达式。在这里我选用的正则表达式,下面是我的处理方法(本文仅提供思路和参考代码,可能不能直接使用)。
模板文件解析类:
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.']不存在!'); } } private function gettplpath($tpl) { $this->folder = website_dirroot. $globals['cfg_tpl_root']; return $this->folder.'/'.$tpl; } private function 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('模板文件内容为空!'); } return 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; tags::$vars = &$this->vars; } } public function display($bool=false, $name=, $time=0) { if (!empty($this->html)) { if ($bool && !empty($name)) { if (!is_int($time)) $time = 600; $cache = new cache($time); $cache->set($name, $this->html); } echo $this->html; flush(); } else { exit('模板文件内容为空!'); } } public function setassign($souc, $info) { if (!empty($this->html)) { $this->html = str_ireplace($souc, self::fmttplhtml($info), $this->html); } else { exit('模板文件内容为空!'); } } private function settpltags() { $this->setpaneltags(); $this->settrunktags(); $this->reghatchvars(); } private function setpaneltags() { $rule = $this->btag.'([^'.$this->eflag.']+)\/'.$this->eflag; preg_match_all('/'.$rule.'/ism', $this->html, $out_matches); $this->transtag($out_matches, 'panel'); unset($out_matches); } private function settrunktags() { $rule = $this->btag.'(\w+)\s*([^'.$this->eflag.']*?)'.$this->eflag. '((?:(?!'.$this->btag.')[\s\s]*?|(?r))*)'.$this->etag.'\\1\s*'.$this->eflag; preg_match_all('/'.$rule.'/ism', $this->html, $out_matches); $this->transtag($out_matches, 'trunk'); unset($out_matches); } private function transtag($result, $type) { if (!empty($result[0])) { switch ($type) { case 'panel' : { for ($i = 0; $i html = str_ireplace($result[0][$i], $html, $this->html); } } } else { $rule = '^([^\s]+)\s*([\s\s]+)$'; 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); } } break; } case 'trunk' : { for ($i = 0; $i html = str_ireplace($result[0][$i], $html, $this->html); } } break; } default: break; } } else { return false; } } private function reghatchvars() { $this->setpaneltags(); } function __destruct() {} }?>
标签解析类:(目前暂时提供data、list两种标签的解析,说明思路)
btag.'if\s+([^'.$that->eflag.']+)\s*'.$that->eflag; $html = preg_replace('/'.$rule.'/ism', '', $html); $rule = $that->btag.'elseif\s+([^'.$that->eflag.']+)\s*'.$that->eflag; $html = preg_replace('/'.$rule.'/ism', '', $html); $rule = $that->btag.'else\s*'.$that->eflag; $html = preg_replace('/'.$rule.'/ism', '', $html); $rule = $that->btag.'loop\s+(\s+)\s+(\s+)\s*'.$that->eflag; $html = preg_replace('/'.$rule.'/ism', '', $html); $rule = $that->btag.'loop\s+(\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.'php\s*'.$that->eflag.'((?:(?!'. $that->btag.')[\s\s]*?|(?r))*)'.$that->etag.'php\s*'.$that->eflag; $html = preg_replace('/'.$rule.'/ism', '', $html); return self::tag_execute($html); } static public function 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('标签{list}的内容为空!'); } } static public function 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}的内容为空!'); } } static public function 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); return $html; } static private function tag_havetag($html) { $bool_has = false; $tpl_ins = new template(); 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.')[\s\s]*?|(?r))*)'.$tpl_ins->etag.'\\1\s*'.$tpl_ins->eflag; $bool_has = $bool_has || preg_match('/'.self::$rule.'/ism', $html); unset($tpl_ins); return $bool_has; } static private function 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_'.$i.'
http://www.bkjia.com/phpjc/752370.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/752370.htmltecharticlemvc是模型(model)、视图(view)和控制(controller)的缩写,php中采用mvc模式的目的是实现web系统的职能分工,通俗的说就是把业务逻辑处理从用户界...