PHP – 关于模板的原理和解析
将PHP代码和静态HTML代码进行分离,使代码的可读性和维护性得到显著提高。
使用模板引擎:
我们所说的模板是web模板,是主要由HTML标记组成的语言来编写的语言,但也有如何表示包含动态生成内容的方式(解析标签)。模板引擎是一种软件库,允许我们从模板生成HTML代码,并制定要包含的动态内容。
模板引擎的特点:
1、 鼓励分离:让各个系统的可读性和维护性得到提高。
2、 促进分工:使得程序员和美工去专心处理自己的设计
3、 比PHP更容易解析:编译文件和缓存文件加载更快,占资源更少。
4、 增加安全性:可限制模板设计师进行不安全的操作,避免误删误访问等。
解析类:
//模板解析类 class Parser{ //创建一个字段保存模板文件里的内容 private $_tpl; //构造方法,用于接收模板文件 public function __construct($_tplFile){ if (!$this->_tpl = file_get_contents($_tplFile)){ exit('模板文件读取错误!'); } } //解析普通变量 private function parVar(){ // preg_match() 执行一个正则表达式匹配 如果第二个参数中包含第一个参数,则返回值为1 // preg_replace() 执行一个正则表达式的搜索和替换 参数1:要被替换的内容 参数2:被替换成的内容 参数3:包含替换内容的变量 // 正则表达式:'/\{\$([\w]+)\}/' 表示匹配{$ } $符后可以为 0-9 ,a-z ,A-Z 的任何值。 即等价为定义的变量 $_patten = '/\{\$([\w]+)\}/'; if (preg_match($_patten,$this->_tpl)){ $this->_tpl = preg_replace($_patten,"<?php echo \$this->_vars['$1'];?>",$this->_tpl); } } //解析if语句 private function parIf(){ //正则表达式 \s :匹配一个或多个空白 \w :匹配a-z,0-9,A-Z和下划线的字符串 $_pattenIf = '/\{if\s+\$([\w]+)\}/'; $_pattenEndIf = '/\{\/if\}/'; $_pattenElse = '/\{else\}/'; if (preg_match($_pattenIf,$this->_tpl)){ if (preg_match($_pattenEndIf,$this->_tpl)){ $this->_tpl = preg_replace($_pattenIf,"<?php if (\$this->_vars['$1']){ ?>",$this->_tpl); $this->_tpl = preg_replace($_pattenEndIf,"<?php } ?>",$this->_tpl); if (preg_match($_pattenElse,$this->_tpl)){ $this->_tpl = preg_replace($_pattenElse,"<?php }else{ ?>",$this->_tpl); } }else{ exit('if语句没有关闭!'); } } } //解析include语句 private function parInclude(){ $_patten = '/\{include\s+file=\"([\w\.\-]+)\"\}/'; // preg_match()的第三个参数 将第一个参数和其分组文件以数组的形式表达 [0]=>{include file="test.php"} [1]=>test.php if (preg_match($_patten,$this->_tpl,$_file)){ if (!file_exists($_file[1]) || empty($_file)){ exit('包含文件出错!'); } $this->_tpl = preg_replace($_patten,"<?php include '$1'; ?>",$this->_tpl); } } //解析PHP代码注释 private function parCommon(){ $_patten = '/\{#\}(.*)\{#\}/'; // 正则表达式 (.* )表示任何内容 if (preg_match($_patten,$this->_tpl)){ $this->_tpl = preg_replace($_patten,"<?php /* $1 */ ?>",$this->_tpl); } } //对外共方法 public function compile($_parFile){ //解析模板内容 $this->parVar(); $this->parIf(); $this->parCommon(); $this->parInclude(); //生成编译文件 // file_put_contents() 将一个字符串写入文件 // file_get_contents() 将整个文件读入一个字符串 if (!file_put_contents($_parFile,$this->_tpl)){ exit('编译文件生成出错!'); } } }
模板引擎的整个过程:
1. 当浏览器请求index.php文件时,实例化模板类对象$_tpl = new Templates();
2. 当template实例化的时候,生成两个数组,一个用来存放模板变量,另一个存放系统变量,通过构造方法,判断文件夹是否存在,同时通过XML文件将系统变量数组初始化
3. 通过模板类template的注入方法,assign(),将对应模板index.tpl中变量的index.php内容注入到模板类的私有变量,完成初始化
4. 模板类template类显示方法display()通过实例化解析parser,将取到的注入变量通过解析类进行解析(即替换)
5. 解析(替换)后,将文件写入PHP、HTML混全文件
6. 通过template类的显示方法将文件输出
缓存
1. 第一次执行显示方法时,将会把PHP、HTML混合文件,生成纯静态的缓存文件
2. 调用缓存文件,显示页面
3. 当浏览器再次调用显示方法时,首先根据各文件的最后修改时间,判断是否重新生成缓存文件或直接调用已存在的缓存文件
重点
通过正则表达式进行字符串的替换
本文参考:
https://wenku.baidu.com/view/18a04351591b6bd97f192279168884868762b8f2.html
https://blog.csdn.net/Qjy_985211/article/details/80872752