php tpl模板引擎定义与使用示例


Posted in PHP onAugust 09, 2019

本文实例讲述了php tpl模板引擎定义与使用。分享给大家供大家参考,具体如下:

tpl.php

<?php
namespace tpl;
/**
* Class Tpl
*/
class Tpl
{
  protected $view_dir;//模板文件
  protected $cache_dir;//缓存文件
  protected $lifetime;//过期时间
  protected $vars = [];//存放显示变量的数组
   /**
   * Tpl constructor.
   * @param string $view_dir
   * @param string $cache_dir
   * @param string $lifetime
   */
  public function __construct($view_dir='', $cache_dir='', $lifetime='')
  {
    //如果模板文件不为空,则设置,为空则为默认值
    if (!empty($view_dir)) {
      if ($this->check_dir($view_dir)) {
        $this->view_dir = $view_dir;
      }
    }
    //如果缓存文件不为空,则设置,为空时为默认值
    if (!empty($cache_dir)) {
      if ($this->check_dir($cache_dir)) {
        $this->cache_dir = $cache_dir;
      }
    }
    //如果过期时间不为空,则设置,为空时为默认值
    if (!empty($lifetime)) {
      $this->lifetime = $lifetime;
    }
  }
   /**
   * 对外公开的方法
   * @param string $name
   * @param string $value
   */
  public function assign($name, $value)
  {
    $this->vars[$name] = $value;//将传入的参数以键值对存入数组中
  }
   /**
   * 测试文件
   * @param $dir_path
   * @return bool
   */
  protected function check_dir($dir_path)
  {
    //如果文件不存在或不是文件夹,则创建
    if (!file_exists($dir_path) || !is_dir($dir_path)) {
      return mkdir($dir_path, 0777, true);
    }
    //如果文件不可读或不可写,则设置模式
    if (!is_writable($dir_path) || !is_readable($dir_path)) {
      return chmod($dir_path, 0777);
    }
    return true;
  }
   /**
   * 展示方法
   * @param $view_name
   * @param bool $isInclude
   * @param null $uri
   */
  public function display($view_name, $isInclude=true, $uri=null)
  {
    //通过传入的文件名,得到模板文件路径
    $view_path = rtrim($this->view_dir, '/') . '/' . $view_name;
    //判断路径是否存在
    if (!file_exists($view_path)) {
      die('文件不存在');
    }
    //通过传入的文件名得到缓存文件名
    $cache_name = md5($view_name . $uri) . '.php';
    //缓过缓存文件名得到缓存路径
    $cache_path = rtrim($this->cache_dir, '/') . '/' .$cache_name;
    //判断缓存文件是否存在,如果不存在,重新生成
    if (!file_exists($cache_path)) {
      $php = $this->compile($view_path);//解析模板文件
      file_put_contents($cache_path, $php);//缓存文件重新生成
    } else {
      //如果缓存文件存在,判断是否过期,判断模板文件是否被修改
      $is_time_out = (filectime($cache_path) + $this->lifetime) > time() ? false : true;
      $is_change = filemtime($view_path) > filemtime($cache_path) ? true : false;
      //如果缓存文件过期或模板文件被修改,重新生成缓存文件
      if ($is_time_out || $is_change) {
        $php = $this->compile($view_path);
        file_put_contents($cache_path, $php);
      }
    }
    if ($isInclude) {
      extract($this->vars);//解析传入变量的数组
      include $cache_path;//展示缓存
    }
  }
   /**
   * 正则解析模板文件
   * @param string $file_name
   * @return mixed|string
   */
  protected function compile($file_name)
  {
    $html = file_get_contents($file_name);//获取模板文件
    //正则转换数组
    $array = [
      '{$%%}' => '<?=$\1?>',
      '{foreach %%}' => '<?php foreach (\1): ?>',
      '{/foreach}' => '<?php endforeach ?>',
      '{include %%}' => '',
      '{if %%}' => '<?php if (\1): ?>',
      '{/if}' => '<?php endif ?>',
      '{for %%}' => '<?php for (\1): ?>',
      '{/for}' => '<?php endfor ?>',
      '{switch %%}' => '<?php switch (\1) ?>',
      '{/switch}' => '<?php endswitch ?>'
    ];
    //遍历数组,生成正则表达式
    foreach ($array AS $key=>$value) {
      //正则表达式,
      $pattern = '#' . str_replace('%%', '(.+?)' , preg_quote($key, '#')) . '#';
      if (strstr($pattern, 'include')) {
        $html = preg_replace_callback($pattern, [$this, 'parseInclude'], $html);
      } else {
        $html = preg_replace($pattern, $value, $html);
      }
    }
    return $html;
  }
   /**
   * 处理include表达式
   * @param array $data
   * @return string
   */
  protected function parseInclude($data)
  {
    $file_name = trim($data[1], '\'"');
    $this->display($file_name, false);
    $cache_name = md5($file_name) . '.php';
    $cache_path = rtrim($this->cache_dir, '/') . '/' . $cache_name;
    return '<?php include "'.$cache_path.'" ?>';
  }
}

user_tpl,,,,从数据库中取值,作为参数传到模板文件,再解析模板文件

<?php
include './sql/pdo.sql.php';
include 'tpl.php';
 $tpl = new tpl\Tpl('./view/', './cache/', 3000);
$link = new pdo_sql();
$dat = ['menu_name', 'menu_url'];
$res = $link->table('blog_menu')->field($dat)->order('id ASC')->select();
$tpl->assign('menu', $res);
$tpl->display('index.html');

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
phpmyadmin导入(import)文件限制的解决办法
Dec 11 PHP
收藏的PHP常用函数 推荐收藏保存
Feb 21 PHP
PHP中防止SQL注入攻击和XSS攻击的两个简单方法
Apr 15 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
Jan 13 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(三)
Jun 23 PHP
PHP中魔术变量__METHOD__与__FUNCTION__的区别
Sep 29 PHP
PHP中文编码小技巧
Dec 25 PHP
php更新mysql后获取改变行数的方法
Dec 25 PHP
十大使用PHP框架的理由
Sep 26 PHP
WordPress中用于获取文章作者与分类信息的方法整理
Dec 17 PHP
php自定义函数实现JS的escape的方法示例
Jul 07 PHP
PHP 获取 ping 时间的实现方法
Sep 29 PHP
php函数式编程简单示例
Aug 08 #PHP
因str_replace导致的注入问题总结
Aug 08 #PHP
PHP goto语句用法实例
Aug 06 #PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
Aug 06 #PHP
Yii框架核心组件类实例详解
Aug 06 #PHP
PHP使用Session实现上传进度功能详解
Aug 06 #PHP
PHP使用ajax的post方式下载excel文件简单示例
Aug 06 #PHP
You might like
PHP学习之PHP表达式
2006/10/09 PHP
php中实现记住密码自动登录的代码
2011/03/02 PHP
抛弃 PHP 代价太高
2016/04/26 PHP
PHP 判断字符串是中文还是英文, 或者是中英混合
2021/03/09 PHP
理解JavaScript变量作用域更轻松
2009/10/25 Javascript
IE本地存储userdata的一个bug说明
2010/07/01 Javascript
Prototype源码浅析 Enumerable部分(二)
2012/01/18 Javascript
js data日期初始化的5种方法
2013/12/29 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
JavaScript保留关键字汇总
2015/12/01 Javascript
Nodejs中 npm常用命令详解
2016/07/04 NodeJs
vuejs在解析时出现闪烁的原因及防止闪烁的方法
2016/09/19 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
Vue-Router进阶之滚动行为详解
2017/09/13 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
Vue指令之 v-cloak、v-text、v-html实例详解
2019/08/08 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
Vue 实现拨打电话操作
2020/11/16 Javascript
[47:53]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#2COL VS Spirit
2016/03/02 DOTA
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
python通过ssh-powershell监控windows的方法
2015/06/02 Python
实例讲解Python中SocketServer模块处理网络请求的用法
2016/06/28 Python
Python入门_浅谈for循环、while循环
2017/05/16 Python
利用Opencv实现图片的油画特效实例
2021/02/28 Python
常用的HTML5列表标签
2017/06/20 HTML / CSS
La Redoute英国官网:法国时尚品牌
2017/04/27 全球购物
德国传统玻璃制造商:Cristalica
2018/04/23 全球购物
Probikekit欧盟:在线公路自行车专家
2019/07/12 全球购物
高中毕业生自我鉴定范文
2013/09/26 职场文书
演讲稿开场白台词
2014/08/25 职场文书
县政府办公室领导班子个人对照检查材料
2014/09/16 职场文书
2014年销售工作总结
2014/12/01 职场文书
学期个人工作总结
2015/02/13 职场文书
Python中json.dumps()函数的使用解析
2021/05/17 Python
python微信智能AI机器人实现多种支付方式
2022/04/12 Python