php模板引擎技术简单实现


Posted in PHP onMarch 15, 2016

用了smarty,tp过后,也想了解了解其模板技术是怎么实现,于是写一个简单的模板类,大致就是读取模板文件->替换模板文件的内容->保存或者静态化 

tpl.class.php主要解析

assign 方法实现     

/**
     * 模板赋值操作
     * @param mixed $tpl_var 如果是字符串,就作为数组索引,如果是数组,就循环赋值
     * @param mixed $tpl_value 当$tpl_var为string时的值,默认为 null
     */
    public function assign($tpl_var,$tpl_value=null){
      if(is_array($tpl_var) && count($tpl_var) > 0){
        foreach ($tpl_var as $k => $v) {
          $this->tpl_vars[$k] = $v;
        }
      }elseif($tpl_var){
        $this->tpl_vars[$tpl_var] = $tpl_value;
      }
    }

fetch 方法实现

/**
      * 生成编译文件
      * @param string $tplFile 模板路径
      * @param string $comFile 编译路径
      * @return string
     */
    private function fetch($tplFile,$comFile){

      //判断编译文件是否需要重新生成(编译文件是否存在或者模板文件修改时间大于编译文件的修改时间)
      if(!file_exists($comFile) || filemtime($tplFile) > filemtime($comFile)){
        //编译,此处也可以使用ob_start()进行静态化
        $content = $this->tplReplace(file_get_contents($tplFile));
        file_put_contents($comFile, $content);
      }

    }

简单编译方法:按照规则进行正则替换

/**
     * 编译文件
     * @param string $content 待编译的内容
     * @return string
     */
    private function tplReplace($content){
      //转义左右定界符 正则表达式字符
      $left = preg_quote($this->left_delimiter,'/');
      $right = preg_quote($this->right_delimiter,'/');

      //简单模拟编译 变量
      $pattern = array(
          //例如{$test}
          '/'.$left.'\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)'.$right.'/i'
        );

      $replace = array(
          '<?php echo $this->tpl_vars[\'${1}\']; ?>'
        );

      //正则处理
      return preg_replace($pattern, $replace, $content);
    }

display = fetch+echo

/**
     * 输出内容
     * @param string $fileName 模板文件名
     */
    public function display($fileName){
      //模板路径
      $tplFile = $this->template_dir.'/'.$fileName;

      //判断模板是否存在
      if(!file_exists($tplFile)){
        $this->errorMessage = '模板文件不存在';
        return false;
      }

      //编译后的文件
      $comFile = $this->compile_dir.'/'.md5($fileName).'.php';

      $this->fetch($tplFile,$comFile);
      
 include $comFile;
    }

其他属性

//模板文件存放位置
    private $template_dir = 'templates'; 

    //编译文件存放位置
    private $compile_dir = 'compiles';

    //左定界符
    private $left_delimiter = '{';

    //右定界符 
    private $right_delimiter = '}'; 

    //内部临时变量,存储用户赋值
    private $tpl_vars = array();

    //错误信息
    private $errorMessage = '';

    /**
     * 修改类属性的值
     * @param array $configs 需要修改的相关属性及值
     * @return bool
     */
    public function setConfigs(array $configs){
      if(count($configs) > 0){
        foreach ($configs as $k => $v) {
          if(isset($this->$k))
            $this->$k = $v;
        }
        return true;
      }
      return false;
    }

测试

模板文件 testTpl.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>test_tpl_demo</title>
</head>
<body>
  {$name}:{$age}:{$message}
</body>
</html>
运行文件 test_tpl.php
<?php
  require 'Tpl.class.php';
  
  $tpl = new Tpl();
  $tplarr = array(
      'name'=>'waited',
      'age'=>'100'
    );
  $tpl->assign($tplarr);
  $tpl->assign('message','this is a demo');
  $tpl->display('testTpl.html');

?>

输出:waited:100:this is a demo

生成编译文件:972fa4d270e295005c36c1dbc7e6a56c.php

以上就是本文的全部内容,希望对大家的学习有所帮助。

PHP 相关文章推荐
通过对php一些服务器端特性的配置加强php的安全
Oct 09 PHP
用定制的PHP应用程序来获取Web服务器的状态信息
Oct 09 PHP
PHP之变量、常量学习笔记
Mar 27 PHP
linux下使用ThinkPHP需要注意大小写导致的问题
Aug 02 PHP
10条PHP高级技巧[修正版]
Aug 02 PHP
dhtmlxTree目录树增加右键菜单以及拖拽排序的实现方法
Apr 26 PHP
PHP在线生成二维码(google api)的实现代码详解
Jun 04 PHP
yii上传文件或图片实例
Apr 01 PHP
PHP中的Streams详细介绍
Nov 12 PHP
PHP语法小结之基础和变量
Nov 22 PHP
PHP Cookei记录用户历史浏览信息的代码
Feb 03 PHP
Yii框架日志记录Logging操作示例
Jul 12 PHP
9个比较实用的php代码片段
Mar 15 #PHP
Laravel使用Caching缓存数据减轻数据库查询压力的方法
Mar 15 #PHP
php图片添加文字水印实现代码
Mar 15 #PHP
PHP闭包函数传参及使用外部变量的方法
Mar 15 #PHP
Yii rules常用规则示例
Mar 15 #PHP
基于laravel制作APP接口(API)
Mar 15 #PHP
使用Composer安装Yii框架的方法
Mar 15 #PHP
You might like
Laravel程序架构设计思路之使用动作类
2018/06/07 PHP
JQuery扩展插件Validate—6 radio、checkbox、select的验证
2011/09/05 Javascript
Jquery实现页面加载时弹出对话框代码
2013/04/19 Javascript
javascript结合canvas实现图片旋转效果
2015/05/03 Javascript
nodejs 中模拟实现 emmiter 自定义事件
2016/02/22 NodeJs
JavaScript 函数模式详解及示例
2016/09/07 Javascript
Ajax使用原生态JS验证用户名是否存在
2020/05/26 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
2016/12/19 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
BootStrap注意事项小结(五)表单
2017/03/10 Javascript
使用Vue-Router 2实现路由功能实例详解
2017/11/14 Javascript
微信小程序新手教程之启动页的重要性
2019/03/03 Javascript
vue 中使用 watch 出现了如下的报错的原因分析
2019/05/21 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
JavaScript异步操作的几种常见处理方法实例总结
2020/05/11 Javascript
2分钟实现一个Vue实时直播系统的示例代码
2020/06/05 Javascript
[00:31]DOTA2荣耀之路7:Miracle-空血无敌斩
2018/05/31 DOTA
Python Web框架Pylons中使用MongoDB的例子
2013/12/03 Python
python k-近邻算法实例分享
2014/06/11 Python
python turtle 绘制太极图的实例
2019/12/18 Python
Python表达式的优先级详解
2020/02/18 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
Python类的继承super相关原理解析
2020/10/22 Python
巧用CSS3 border实现图片遮罩效果代码
2012/04/09 HTML / CSS
Flesh Beauty官网:露华浓集团旗下彩妆品牌
2021/02/15 全球购物
CK澳大利亚官网:Calvin Klein澳大利亚
2020/12/12 全球购物
如何找出EMP表里面SALARY第N高的employee
2013/12/05 面试题
LINUX下线程,GDI类的解释
2016/12/14 面试题
结婚典礼证婚词
2014/01/11 职场文书
白酒市场营销方案
2014/02/25 职场文书
初中班主任寄语
2014/04/04 职场文书
党员领导干部承诺书
2014/05/28 职场文书
美术专业自荐信
2014/07/07 职场文书
大学生感恩父母演讲稿
2014/08/28 职场文书
导游词之桂林山水
2019/09/20 职场文书
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python