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和ACCESS写聊天室(七)
Oct 09 PHP
php 在文件指定行插入数据的代码
May 08 PHP
解析:php调用MsSQL存储过程使用内置RETVAL获取过程中的return值
Jul 03 PHP
PHP仿博客园 个人博客(2) 数据库增添改删
Jul 05 PHP
取得单条网站评论以数组形式进行输出
Jul 28 PHP
php将12小时制转换成24小时制的方法
Mar 31 PHP
浅析iis7.5安装配置php环境
May 10 PHP
php操作MongoDB类实例
Jun 17 PHP
详解WordPress开发中过滤属性以及Sql语句的函数使用
Dec 25 PHP
详谈PHP中的密码安全性Password Hashing
Feb 04 PHP
php7 安装yar 生成docker镜像
May 09 PHP
php实现的rc4加密解密类定义与用法示例
Aug 16 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
[原创]效率较高的php下读取文本文件的代码
2008/07/02 PHP
求PHP数组最大值,最小值的代码
2011/10/31 PHP
windows的文件系统机制引发的PHP路径爆破问题分析
2014/07/28 PHP
浅析iis7.5安装配置php环境
2015/05/10 PHP
jQuery的each循环用法简单示例
2016/06/12 Javascript
AngularJS用户选择器指令实例分析
2016/11/04 Javascript
8 行 Node.js 代码实现代理服务器
2016/12/05 Javascript
vue多层嵌套路由实例分析
2019/03/19 Javascript
巧妙运用v-model实现父子组件传值的方法示例
2019/04/07 Javascript
vue实现简单的日历效果
2020/09/24 Javascript
微信小程序实现3D轮播图效果(非swiper组件)
2019/09/21 Javascript
Vue 实现对quill-editor组件中的工具栏添加title
2020/08/03 Javascript
Vue与React的区别和优势对比
2020/12/18 Vue.js
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
Python转换时间的图文方法
2019/07/01 Python
python使用socket 先读取长度,在读取报文内容示例
2019/09/26 Python
python topk()函数求最大和最小值实例
2020/04/02 Python
python爬虫判断招聘信息是否存在的实例代码
2020/11/20 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
前端隐藏出边界内容的实现方法
2016/04/14 HTML / CSS
css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果
2021/01/27 HTML / CSS
美国最大的宠物用品零售商:PetSmart
2016/11/14 全球购物
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
Ramy Brook官网:美国现代女装品牌
2019/06/18 全球购物
公司员工的自我评价范例
2013/11/01 职场文书
初中化学教学反思
2014/01/23 职场文书
体育比赛口号
2014/06/09 职场文书
注册资产评估专业求职信
2014/07/16 职场文书
2014年网络管理员工作总结
2014/12/01 职场文书
2014年党小组工作总结
2014/12/20 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
大学生个人总结范文
2015/02/15 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书
经典励志格言:每日一句,让你每天充满能量
2019/08/16 职场文书
Ruby处理CSV数据方法详解
2022/04/18 Ruby
使用CSS定位HTML元素的实现方法
2022/07/07 HTML / CSS