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 相关文章推荐
真正的ZIP文件操作类(php)
Jul 21 PHP
PHP页面间传递参数实例代码
Jun 05 PHP
php中如何同时使用session和cookie来保存用户登录信息
Jul 05 PHP
PHP实现的连贯操作、链式操作实例
Jul 08 PHP
支付宝接口开发集成支付环境小结
Mar 17 PHP
解决yii2左侧菜单子级无法高亮问题的方法
May 08 PHP
提交表单后 PHP获取提交内容的实现方法
May 25 PHP
PHP 接入微信扫码支付总结(总结篇)
Nov 03 PHP
PHP设计模式之工厂模式实例总结
Sep 01 PHP
php从数据库中获取数据用ajax传送到前台的方法
Aug 20 PHP
Laravel5.4框架使用socialite实现github登录的方法
Mar 20 PHP
Yii框架安装简明教程
May 15 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
基于mysql的论坛(2)
2006/10/09 PHP
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
2014/10/29 PHP
php获取网页上所有链接的方法
2015/04/03 PHP
PHP的Yii框架入门使用教程
2016/02/15 PHP
php无法连接mysql数据库的正确解决方法
2016/07/01 PHP
PHP memcache在微信公众平台的应用方法示例
2017/09/13 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
jQuery mobile类库使用时加载导航历史的方法简介
2015/12/04 Javascript
javascript中eval解析JSON字符串
2016/02/27 Javascript
Ajax实现不刷新取最新商品
2017/03/01 Javascript
无循环 JavaScript(map、reduce、filter和find)
2017/04/08 Javascript
简单实现JS上传图片预览功能
2017/04/14 Javascript
vue封装第三方插件并发布到npm的方法
2017/09/25 Javascript
最新Javascript程序员面试试题和解题方法
2017/11/23 Javascript
Vue项目分环境打包的实现步骤
2018/04/02 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
vue 不使用select实现下拉框功能(推荐)
2018/05/17 Javascript
vue中axios请求的封装实例代码
2019/03/23 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
2019/04/26 Javascript
kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.
2019/09/17 Javascript
layui form表单提交后实现自动刷新
2019/10/25 Javascript
js实现图片无缝循环轮播
2019/10/28 Javascript
vue路由切换之淡入淡出的简单实现
2019/10/31 Javascript
Python六大开源框架对比
2015/10/19 Python
Python程序退出方式小结
2017/12/09 Python
python 实现对数据集的归一化的方法(0-1之间)
2018/07/17 Python
Python中的 is 和 == 以及字符串驻留机制详解
2019/06/28 Python
python两个list[]相加的实现方法
2020/09/23 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
canvas版人体时钟的实现示例
2021/01/29 HTML / CSS
世界首屈一指的在线男士内衣权威:HisRoom
2017/08/05 全球购物
佳能法国商店:Canon法国
2019/02/14 全球购物
KENZO官网:高田贤三在法国创立的品牌
2019/05/16 全球购物
十一国庆节“向国旗敬礼”主题班会活动方案
2014/09/27 职场文书
婚育证明样本
2015/06/16 职场文书