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 相关文章推荐
文章推荐系统(三)
Oct 09 PHP
用PHP4访问Oracle815
Oct 09 PHP
php5 mysql分页实例代码
Apr 10 PHP
Zend Studio for Eclipse的java.lang.NullPointerException错误的解决方法
Dec 06 PHP
php简单的留言板与回复功能具体实现
Feb 19 PHP
简单的php新闻发布系统教程
May 09 PHP
php实现以只读方式打开文件的方法
Mar 16 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
Jul 28 PHP
最准确的php截取字符串长度函数
Oct 29 PHP
php读取和保存base64编码的图片内容
Apr 22 PHP
PHP那些琐碎的知识点(整理)
May 20 PHP
php使用event扩展的io复用测试的示例
Oct 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 4.2书写安全的脚本
2006/10/09 PHP
简单介绍下 PHP5 中引入的 MYSQLI的用途
2007/03/19 PHP
php获取post中的json数据的实现方法
2011/06/08 PHP
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
destoon二次开发入门示例
2014/06/20 PHP
php检测url是否存在的方法
2015/04/14 PHP
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
js 禁用浏览器的后退功能的简单方法
2008/12/10 Javascript
一个tab标签切换效果代码
2009/03/27 Javascript
jQuery温习篇 强大的JQuery选择器
2010/04/24 Javascript
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
Javascript 面向对象(三)接口代码
2012/05/23 Javascript
bootstrap读书笔记之CSS组件(上)
2016/10/17 Javascript
JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
2016/12/12 Javascript
使用JavaScript判断用户输入的是否为正整数(两种方法)
2017/02/05 Javascript
Vue keep-alive实践总结(推荐)
2017/08/31 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
Vuepress 搭建带评论功能的静态博客的实现
2019/02/17 Javascript
js中关于Blob对象的介绍与使用
2019/11/29 Javascript
JavaScript实现随机点名程序
2020/03/25 Javascript
[29:23]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场1
2014/05/23 DOTA
[01:04:31]DOTA2-DPC中国联赛定级赛 iG vs Magma BO3第二场 1月8日
2021/03/11 DOTA
python中常用的各种数据库操作模块和连接实例
2014/05/29 Python
python中执行shell命令的几个方法小结
2014/09/18 Python
Django中实现点击图片链接强制直接下载的方法
2015/05/14 Python
python更改已存在excel文件的方法
2018/05/03 Python
Python装饰器基础概念与用法详解
2018/12/22 Python
python numpy实现rolling滚动案例
2020/06/08 Python
Python pip 常用命令汇总
2020/10/19 Python
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
档案管理员岗位职责
2013/12/01 职场文书
2015年街道除四害工作总结
2015/05/15 职场文书
pycharm 如何查看某一函数源码的快捷键
2021/05/12 Python
粗暴解决CUDA out of memory的问题
2021/05/22 Python
俄罗斯十大城市人口排名,第三首都仅排第六,第二是北方首都
2022/03/20 杂记