php网站模板原理,PHP关于模板的原理和解析

将PHP代码和静态HTML代码进行分离,使代码的可读性和维护性得到显著提高。

使用模板引擎:

我们所说的模板是Web模板,是主要由HTML标记组成的语言来编写的页面,但也有如何表示包含动态生成内容的方式(解析标签)。模板引擎是一种软件库,允许我们从模板生成HTML代码,并指定要包含的动态内容。

模板引擎的特点:

1.鼓励分离:让更个系统的可读性和维护性得到提高。  2.促进分工:使得程序员和美工去专心处理自己的设计。  3.比PHP更容易解析:编译文件和缓存文件加载更快、占资源更少。  4.增加安全性:可限制模板设计师进行不安全的操作的能力避免误删误访问等。

模板处理的流程图

0818b9ca8b590ca3270a3433284dd417.png

创建模板:

1、创建初始模板所需要的文件夹和文件。

a) index.php主文件,用于编写业务逻辑。  b) template.inc.php模板初始化文件,用于初始模版信息。  c) templates目录存放所有的模板文件。  d) templates_c目录存放所有编译文件。  e) cache目录存放所有缓存文件。  f) includes目录存放所有的类文件。  g) config目录存放模板系统变量配置文件。

0818b9ca8b590ca3270a3433284dd417.png

以下是源码:

主文件 index.php

//index.php

//设置编码为UTF-8

header('Content-Type:text/html;Charset=utf-8');

//网站根目录

define('ROOT_PATH', dirname(__FILE__));

//存放模板文件夹

define('TPL_DIR', ROOT_PATH.'/templates/');

//编译文件夹

define('TPL_C_DIR', ROOT_PATH.'/templates_c/');

//缓存文件夹

define('CACHE_DIR', ROOT_PATH.'/cache/');

//定义缓存状态

define('IS_CACHE',true);

//设置缓存状态开关

IS_CACHE ? ob_start() : null;

include ROOT_PATH.'/includes/Templates.class.php';

$_name = '方块李';

$array = array(1,2,3,4,5,6);

$_tpl = new Templates();

$_tpl->assign('name', $_name);

$_tpl->assign('a', 5>4);

$_tpl->assign('array', $array);

//显示

$_tpl->display('index.tpl');

?>

模板文件 HTML

title>

head>

{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) < filemtime($_tplFile))){

//引入模板解析类

require ROOT_PATH.'/includes/Parser.class.php';

//实例化对象,生成编译文件

$_parser = new Parser($_tplFile);//模板文件

$_parser->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,"<?php echo \$this->_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, "<?php if(\$this->_vars['$1']){ ?>", $this->_tpl);

//替换结尾IF

$this->_tpl = preg_replace($_patternEnd, "<?php } ?>", $this->_tpl);

//判断是否有else

if(preg_match($_patternElse, $this->_tpl)){

//替换else

$this->_tpl = preg_replace($_patternElse, "<?php }else{ ?>", $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, "<?php foreach(\$this->_vars['$1'] as \$$2=>\$$3){?>", $this->_tpl);

//替换结束

$this->_tpl = preg_replace($_patternEndForeach, "<?php } ?>", $this->_tpl);

//替换值

$this->_tpl = preg_replace($_patternVar, "<?php echo \$$1?>", $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, "<?php include '$1';?>", $this->_tpl);

}

}

//解析系统变量

private function configVar(){

$_pattern = '//';

if(preg_match($_pattern, $this->_tpl,$_file)){

$this->_tpl = preg_replace($_pattern,"<?php echo \$this->_config['$1'] ?>", $this->_tpl);

}

}

//解析单行PHP注释

private function parCommon(){

$_pattern = '/\{#\}(.*)\{#\}/';

if(preg_match($_pattern, $this->_tpl)){

$this->_tpl = preg_replace($_pattern, "<?php /*($1) */?>", $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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值