PHP--关于模板的原理和解析,php--模板解析_PHP教程

PHP--关于模板的原理和解析,php--模板解析_PHP教程,第1张

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


此内容用作笔记,以备日后查看,此内容为学习李炎恢课程而来,并非自己所创,如有问题请私信~

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


使用模板引擎:

我们所说的模板是Web模板,是主要由HTML标记组成的语言来编写的页面,但也有如何表示包含动态生成内容的方式(解析标签)。


模板引擎是一种软件库,允许我们从模板生成HTML代码,并指定要包含的动态内容。


  模板引擎的特点:

  1.鼓励分离:让更个系统的可读性和维护性得到提高。



  2.促进分工:使得程序员和美工去专心处理自己的设计。



  3.比PHP更容易解析:编译文件和缓存文件加载更快、占资源更少。



  4.增加安全性:可限制模板设计师进行不安全的 *** 作的能力避免误删误访问等。


模板处理的流程图

  PHP--关于模板的原理和解析,php--模板解析_PHP教程,第2张

创建模板:

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


  a) index.php主文件,用于编写业务逻辑。



  b) template.inc.php模板初始化文件,用于初始模版信息。



  c) templates目录存放所有的模板文件。



  d) templates_c目录存放所有编译文件。



  e) cache目录存放所有缓存文件。



  f) includes目录存放所有的类文件。



  g) config目录存放模板系统变量配置文件。


  PHP--关于模板的原理和解析,php--模板解析_PHP教程,第3张

  以下是源码:

主文件 index.php  

<?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




<!--{webname}-->



{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 = '/{ifs+$([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 = '/{foreachs+$(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 = '/{includes+"(.*)"}/';
	        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--模板解析 此内容用作笔记,以备日后查看,此内容为学习李炎恢课程而来,并非自己所创,如有问题请...

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/zaji/476112.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2018-06-02
下一篇 2018-06-02

发表评论

登录后才能评论

评论列表(0条)

保存