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 相关文章推荐
初探PHP5
Oct 09 PHP
基于mysql的论坛(7)
Oct 09 PHP
使用PHP提取视频网站页面中的FLASH地址的代码
Apr 17 PHP
PHP中文件上传的一个问题
Sep 04 PHP
php检测网页是否被百度收录的函数代码
Oct 09 PHP
php中cookie的使用方法
Mar 29 PHP
PHPUnit安装及使用示例
Oct 29 PHP
WordPress导航菜单的滚动和淡入淡出效果的实现要点
Dec 14 PHP
PHP匿名函数和use子句用法实例
Mar 16 PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
Apr 01 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
Feb 23 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
Jun 16 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操作Memcache实例介绍
2013/06/14 PHP
PHP限制页面只能在微信自带浏览器访问的代码
2014/01/15 PHP
php集成环境xampp中apache无法启动问题解决方案
2014/11/18 PHP
PHP安装threads多线程扩展基础教程
2015/11/17 PHP
一行代码实现纯数据json对象的深度克隆实现思路
2013/01/09 Javascript
javascript与jquery动态创建html元素示例
2016/07/25 Javascript
Bootstrap导航条学习使用(一)
2017/02/08 Javascript
Vue.js实现一个漂亮、灵活、可复用的提示组件示例
2017/03/17 Javascript
JavaScript中undefined和null的区别
2017/05/03 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
Angular.js自动化测试之protractor详解
2017/07/07 Javascript
Node.JS中快速扫描端口并发现局域网内的Web服务器地址(80)
2017/09/18 Javascript
jQuery中 DOM节点操作方法大全
2017/10/12 jQuery
vue路由跳转时判断用户是否登录功能的实现
2017/10/26 Javascript
layer弹出层父子页面事件相互调用方法
2018/08/17 Javascript
微信小程序开发(二):页面跳转并传参操作示例
2020/06/01 Javascript
vue中echarts图表大小适应窗口大小且不需要刷新案例
2020/07/19 Javascript
[47:20]DAC2018 4.4 淘汰赛 Optic vs Mineski 第一场
2018/04/05 DOTA
python进阶教程之动态类型详解
2014/08/30 Python
Python中的类与对象之描述符详解
2015/03/27 Python
python获取当前运行函数名称的方法实例代码
2017/04/06 Python
Python cookbook(数据结构与算法)实现对不原生支持比较操作的对象排序算法示例
2018/03/15 Python
Python实现的堆排序算法示例
2018/04/29 Python
Python 实现某个功能每隔一段时间被执行一次的功能方法
2018/10/14 Python
基于python生成器封装的协程类
2019/03/20 Python
浅谈python 中类属性共享的问题
2019/07/02 Python
Keras在训练期间可视化训练误差和测试误差实例
2020/06/16 Python
Python 基于jwt实现认证机制流程解析
2020/06/22 Python
Selenium之模拟登录铁路12306的示例代码
2020/07/31 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
python实现三种随机请求头方式
2021/01/05 Python
Python自动化测试基础必备知识点总结
2021/02/07 Python
英国第一独立滑雪板商店:The Snowboard Asylum
2020/01/16 全球购物
2019交通安全宣传标语集锦!
2019/06/28 职场文书
MySQL数据库中的锁、解锁以及删除事务
2022/05/06 MySQL
Hive HQL支持2种查询语句风格
2022/06/25 数据库