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 url地址栏传中文乱码解决方法集合
Jun 25 PHP
Discuz Uchome ajaxpost小技巧
Jan 04 PHP
PHP 自定义错误处理函数的使用详解
May 10 PHP
通过dbi使用perl连接mysql数据库的方法
Apr 16 PHP
php实例分享之通过递归实现删除目录下的所有文件详解
May 15 PHP
php+ajax实现图片文件上传功能实例
Jun 17 PHP
thinkphp获取栏目和文章当前位置的方法
Oct 29 PHP
php生成固定长度纯数字编码的方法
Jul 09 PHP
php类自动装载、链式操作、魔术方法实现代码
Jul 23 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
Dec 21 PHP
PHP实现根据数组某个键值大小进行排序的方法
Mar 13 PHP
php写入文件不覆盖的实例讲解
Sep 17 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
php4与php5的区别小结(配置异同)
2011/12/20 PHP
php socket客户端及服务器端应用实例
2014/07/04 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
基于jquery实现的类似百度搜索的输入框自动完成功能
2011/08/23 Javascript
JS将制定内容复制到剪切板示例代码
2014/02/11 Javascript
JavaScript中的this关键字使用详解
2015/08/14 Javascript
Javascript获取统一管理的提示语(message)
2016/02/03 Javascript
jQuery hover事件简单实现同时绑定2个方法
2016/06/07 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
2016/08/23 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
JavaScript中字符串的常用操作方法及特殊字符
2018/03/18 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
vue cli3.0结合echarts3.0与地图的使用方法示例
2019/03/26 Javascript
layui-table获得当前行的上/下一行数据的例子
2019/09/24 Javascript
小程序富文本提取图片可放大缩小
2020/05/26 Javascript
vue的webcamjs集成方式
2020/11/16 Javascript
vue脚手架项目创建步骤详解
2021/03/02 Vue.js
[01:14]TI珍贵瞬间系列(六):冠军
2020/08/30 DOTA
在Python中使用PIL模块处理图像的教程
2015/04/29 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
django+mysql的使用示例
2018/11/23 Python
Python列表list排列组合操作示例
2018/12/18 Python
PyCharm 设置SciView工具窗口的方法
2019/01/15 Python
python 含子图的gif生成时内存溢出的方法
2019/07/07 Python
tensorflow模型保存、加载之变量重命名实例
2020/01/21 Python
python模拟预测一下新型冠状病毒肺炎的数据
2020/02/01 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
45个非常奇妙的CSS3 特性应用示例
2012/01/01 HTML / CSS
美国领先的医疗警报服务:Philips Lifeline
2018/03/12 全球购物
物流仓储实习自我鉴定
2013/09/25 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
2015年学生会主席工作总结
2015/04/21 职场文书
Python数据分析之pandas读取数据
2021/06/02 Python
mysql外连接与内连接查询的不同之处
2021/06/03 MySQL
css filter和getUserMedia的联合使用
2022/02/24 HTML / CSS