php--关于模板的原理和解析,php--模板解析此内容用作笔记,以备日后查看,此内容为学习李炎恢课程而来,并非自己所创,如有问题请私信~
将php代码和静态html代码进行分离,使代码的可读性和维护性得到显著提高。
使用模板引擎:
我们所说的模板是web模板,是主要由html标记组成的语言来编写的页面,但也有如何表示包含动态生成内容的方式(解析标签)。模板引擎是一种软件库,允许我们从模板生成html代码,并指定要包含的动态内容。
模板引擎的特点:
1.鼓励分离:让更个系统的可读性和维护性得到提高。
2.促进分工:使得程序员和美工去专心处理自己的设计。
3.比php更容易解析:编译文件和缓存文件加载更快、占资源更少。
4.增加安全性:可限制模板设计师进行不安全的操作的能力避免误删误访问等。
模板处理的流程图
创建模板:
1、创建初始模板所需要的文件夹和文件。
a) index.php主文件,用于编写业务逻辑。
b) template.inc.php模板初始化文件,用于初始模版信息。
c) templates目录存放所有的模板文件。
d) templates_c目录存放所有编译文件。
e) cache目录存放所有缓存文件。
f) includes目录存放所有的类文件。
g) config目录存放模板系统变量配置文件。
以下是源码:
主文件 index.php
assign('name', $_name); $_tpl->assign('a', 5>4); $_tpl->assign('array', $array); //显示 $_tpl->display('index.tpl');?>
模板文件 html
{include test.php}{#}这是一条php的注释,在html页面里是不显示的,只会在生成的编译文件里显示{#}我将被index.php导入{$name}这个标签必须经过parser.class.php这个解析类来解析它1
这里的内容改变了,为什么?
{if $a}显示一号皮肤{else}显示二号皮肤{/if}
{foreach $array(key,value)}{@key}....{@value}
{/foreach}
模板类:
//templates.class.php class templates { //创建一个存放数组的字段 private $_vars = array(); private $_config = array(); //创建一个构造方法 public function __construct(){ if(!is_dir(tpl_dir) || !is_dir(tpl_c_dir) || !is_dir(cache_dir) ){ exit('error:模板文件夹或者编译文件夹或者缓存文件夹没有创建!'); } //获取系统变量 $_sxe = simplexml_load_file(root_path.'/config/profile.xml'); $_taglib = $_sxe->xpath('/root/taglib'); foreach($_taglib as $_tag){ $this->_config[$_tag->name] = $_tag->value; } } //创建变量注入方法 /** * assign()变量注入方法 * @param $_var 要注入的变量名,对应.tpl文件中的需要替换的变量 * @param $_values 要注入的变量值 */ public function assign($_var,$_values){ if(isset($_var) && !empty($_var)){ $this->_vars[$_var] = $_values; }else{ exit('error:请设置变量名!'); } } //创建一个显示方法,用来显示编译后的文件 public function display($_file){ //设置模板文件的路径 $_tplfile = tpl_dir.$_file; //判断模板文件是否存在 if(!file_exists($_tplfile)){ exit('error:模板文件不存在'); } //设置编译文件名 $_parfile = tpl_c_dir.md5($_file).$_file.'.php'; //设置缓存文件名 $_cachefile = cache_dir.md5($_file).$_file.'.html'; //判断缓存状态 if(is_cache){ //判断缓存文件是否存在 if(file_exists($_cachefile) && file_exists($_parfile)){ //是否修改过编译文件或者模板文件 if(filemtime($_cachefile)>=filemtime($_parfile) && filemtime($_parfile)>filemtime($_tplfile)){ echo '以下是缓存文件内容'; echo
; include $_cachefile; return; } } } //判断编译文件是否存在,模板文件是否修改过 if(!file_exists($_parfile) || (filemtime($_parfile) compile($_parfile);//编译后文件 } //载入编译文件 include $_parfile; if(is_cache){ //生成缓存文件 file_put_contents($_cachefile, ob_get_contents()); //清除缓冲区 ob_end_clean(); //载入缓存文件 include $_cachefile; } } }
解析类:
//parser.class.php class parser { //获取模板内容 private $_tpl; //构造方法,初始化模板 public function __construct($_tplfile){ //判断文件是否存在 if(!$this->_tpl = file_get_contents($_tplfile)){ exit('error:读取模板出错!'); } } //解析普通变量 private function parvar(){ $_pattern = '/\{\$([\w]+)\}/'; if (preg_match($_pattern,$this->_tpl)) { $this->_tpl = preg_replace($_pattern,_vars['$1'] ?>,$this->_tpl); } } //解析if条件语句 private function parif(){ //开头if模式 $_patternif = '/\{if\s+\$([\w]+)\}/'; //结尾if模式 $_patternend = '/\{\/if\}/'; //else模式 $_patternelse = '/\{else\}/'; //判断if是否存在 if(preg_match($_patternif, $this->_tpl)){ //判断是否有if结尾 if(preg_match($_patternend, $this->_tpl)){ //替换开头if $this->_tpl = preg_replace($_patternif, _vars['$1']){ ?>, $this->_tpl); //替换结尾if $this->_tpl = preg_replace($_patternend, , $this->_tpl); //判断是否有else if(preg_match($_patternelse, $this->_tpl)){ //替换else $this->_tpl = preg_replace($_patternelse, , $this->_tpl); } }else{ exit('error:语句没有关闭!'); } } } //解析foreach private function parforeach(){ $_patternforeach = '/\{foreach\s+\$(\w+)\((\w+),(\w+)\)\}/'; $_patternendforeach = '/\{\/foreach\}/'; //foreach里的值 $_patternvar = '/\{@(\w+)\}/'; //判断是否存在 if(preg_match($_patternforeach, $this->_tpl)){ //判断结束标志 if(preg_match($_patternendforeach, $this->_tpl)){ //替换开头 $this->_tpl = preg_replace($_patternforeach, _vars['$1'] as \$$2=>\$$3){?>, $this->_tpl); //替换结束 $this->_tpl = preg_replace($_patternendforeach, , $this->_tpl); //替换值 $this->_tpl = preg_replace($_patternvar, , $this->_tpl); }else{ exit('error:foreach语句没有关闭'); } } } //解析include private function parinclude(){ $_pattern = '/\{include\s+\(.*)\\}/'; if(preg_match($_pattern, $this->_tpl,$_file)){ //判断头文件是否存在 if(!file_exists($_file[1]) || empty($_file[1])){ exit('error:包含文件不存在!'); } //替换内容 $this->_tpl = preg_replace($_pattern, , $this->_tpl); } } //解析系统变量 private function configvar(){ $_pattern = '//'; if(preg_match($_pattern, $this->_tpl,$_file)){ $this->_tpl = preg_replace($_pattern,_config['$1'] ?>, $this->_tpl); } } //解析单行php注释 private function parcommon(){ $_pattern = '/\{#\}(.*)\{#\}/'; if(preg_match($_pattern, $this->_tpl)){ $this->_tpl = preg_replace($_pattern, , $this->_tpl); } } //生成编译文件 public function compile($_parfile){ //解析模板变量 $this->parvar(); //解析if $this->parif(); //解析注释 $this->parcommon(); //解析foreach $this->parforeach(); //解析include $this->parinclude(); //解析系统变量 $this->configvar(); //生成编译文件 if(!file_put_contents($_parfile, $this->_tpl)){ exit('error:编译文件生成失败!'); } } }
总结:模板引擎的整个过程:
1、当浏览器请求index.php文件时,实例化模板类对像 $_tpl = new templates();
2、当templates实例化的时候,生成两个数组,一个用来存放模板变量,另一个存放系统变量,通过构造方法,判断文件夹是否存在,同时通过xml文件将系统变量数组初始化
3、通过模板类templates的注入方法,assign(),将对应模板index.tpl中变量的index.php的内容注入到模板类的私有变量,完成初始化
4、模板类templates类显示方法display() 通过实例化解析类parser,将取到的注入变量通过解析类进行解析(即替换)
5、解析(替换)后,将文件写入php、html混全文件
6、通过templates类的显示方法将文件输出:
1、第一次执行显示方法时,将会把php、html混合文件,生成纯静态的缓存文件
2、调用缓存文件,显示页面
3、当浏览器再次调用显示方法时,首先根据各文件的最后修改时间,判断是否重新生成缓存文件或直接调用已存在的缓存文件
重点:
1、通过正则表达式进行字符串的替换
2、熟悉oop
http://www.bkjia.com/phpjc/1055139.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/1055139.htmltecharticlephp--关于模板的原理和解析,php--模板解析 此内容用作笔记,以备日后查看,此内容为学习李炎恢课程而来,并非自己所创,如有问题请...