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安装问题
Oct 09 PHP
用PHP函数解决SQL injection
Oct 09 PHP
PHP 上传文件大小限制
Jul 05 PHP
php中的常用魔术方法总结
Aug 02 PHP
php获取mysql字段名称和其它信息的例子
Apr 14 PHP
教你如何快捷的使用cmd访问mysql小技巧
May 26 PHP
PHP+Memcache实现wordpress访问总数统计(非插件)
Jul 04 PHP
php批量添加数据与批量更新数据的实现方法
Dec 16 PHP
thinkphp中多表查询中防止数据重复的sql语句(必看)
Sep 22 PHP
php图像处理函数imagecopyresampled用法详解
Dec 02 PHP
php实现的二叉树遍历算法示例
Jun 15 PHP
Smarty模板变量与调节器实例详解
Jul 20 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防注入代码
2010/04/07 PHP
PHP中的多种加密技术及代码示例解析
2016/10/20 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
laravel admin实现分类树/模型树的示例代码
2020/06/10 PHP
doctype后如何获得body.clientHeight的方法
2007/07/11 Javascript
JavaScript Event学习第八章 事件的顺序
2010/02/07 Javascript
基于jquery的无缝循环新闻列表插件
2011/03/07 Javascript
jQuery数据显示插件整合实现代码
2011/10/24 Javascript
JavaScript 垃圾回收机制分析
2013/10/10 Javascript
Vue学习笔记之表单输入控件绑定
2017/09/05 Javascript
bootstrap paginator分页插件的两种使用方式实例详解
2017/11/14 Javascript
vue通信方式EventBus的实现代码详解
2019/06/10 Javascript
浅谈Three.js截图并下载的大坑
2019/11/01 Javascript
Vue解析剪切板图片并实现发送功能
2020/02/04 Javascript
javascript设计模式 ? 抽象工厂模式原理与应用实例分析
2020/04/09 Javascript
[03:18]DOTA2放量测试专访820:希望玩家加入国服大家庭
2013/08/25 DOTA
Python EOL while scanning string literal问题解决方法
2020/09/18 Python
Python将图片批量从png格式转换至WebP格式
2020/08/22 Python
Python 使用SMTP发送邮件的代码小结
2016/09/21 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
Python中实现单例模式的n种方式和原理
2018/11/14 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
2020/01/09 Python
用HTML5实现手机摇一摇的功能的教程
2012/10/30 HTML / CSS
Perry Ellis官网:美国男士品味服装
2016/12/09 全球购物
英国时尚饰品和发饰购物网站:Claire’s
2017/07/04 全球购物
装潢设计实习自我鉴定
2013/09/19 职场文书
预备党员党课思想汇报
2014/01/13 职场文书
班主任经验交流会主持词
2014/04/01 职场文书
中国梦主题教育活动总结
2014/05/05 职场文书
运动会铅球比赛加油稿
2014/09/26 职场文书
元旦晚会开场白
2015/05/29 职场文书
2016年党员公开承诺书格式范文
2016/03/24 职场文书
MySQL Router的安装部署
2021/04/24 MySQL
PyTorch device与cuda.device用法
2022/04/03 Python