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 相关文章推荐
php程序之die调试法 快速解决错误
Sep 17 PHP
由php的call_user_func传reference引发的思考
Jul 23 PHP
PHP中对用户身份认证实现两种方法
Jun 04 PHP
thinkphp常见路径用法分析
Dec 02 PHP
php实现mysql备份恢复分卷处理的方法
Dec 26 PHP
php判断当前用户已在别处登录的方法
Jan 06 PHP
php获取当月最后一天函数分享
Feb 02 PHP
php上传图片类及用法示例
May 11 PHP
深入分析PHP优化及注意事项
Jul 04 PHP
laravel migrate初学常见错误的解决方法
Oct 11 PHP
PHP递归算法的简单实例
Feb 28 PHP
laravel实现于语言包的完美切换方法
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
2020年4月放送决定!第2期TV动画《邪神酱飞踢》视觉图&主题曲情报公开!
2020/03/06 日漫
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
PHP strncasecmp字符串比较的小技巧
2011/01/04 PHP
从康盛产品(discuz)提取出来的模板类
2011/06/28 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
2012/01/03 PHP
ThinkPHP验证码使用简明教程
2014/03/05 PHP
PHP+Mysql+jQuery文件下载次数统计实例讲解
2015/10/10 PHP
php单例模式的简单实现方法
2016/06/10 PHP
PHP中session跨子域的三种实现方法
2016/07/25 PHP
php分页查询的简单实现代码
2017/03/14 PHP
解决表单中第一个非隐藏的元素获得焦点的一个方案
2009/10/26 Javascript
javascript for循环从入门到偏门(效率优化+奇特用法)
2012/08/01 Javascript
javascript判断两个IP地址是否在同一个网段的实现思路
2013/12/13 Javascript
js常用自定义公共函数汇总
2014/01/15 Javascript
jQuery实现点击按钮弹出可关闭层的浮动层插件
2015/09/19 Javascript
Javascript实现跑马灯效果的简单实例
2016/05/31 Javascript
Highcharts入门之基本属性
2016/08/02 Javascript
JS实现鼠标移上去显示图片或微信二维码
2016/12/14 Javascript
jQuery实现的简单前端搜索功能示例
2017/10/28 jQuery
H5+C3+JS实现双人对战五子棋游戏(UI篇)
2020/05/28 Javascript
Angular(5.2-&gt;6.1)升级小结
2018/12/27 Javascript
详解如何搭建mpvue框架搭配vant组件库的小程序项目
2019/05/16 Javascript
详解利用eventemitter2实现Vue组件通信
2019/11/04 Javascript
微信小程序实现星星评分效果
2020/11/01 Javascript
Python中字典和JSON互转操作实例
2015/01/19 Python
在dataframe两列日期相减并且得到具体的月数实例
2018/07/03 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
在python image 中实现安装中文字体
2020/05/16 Python
python用tkinter实现一个简易能进行随机点名的界面
2020/09/27 Python
Nike俄罗斯官方网站:Nike RU
2021/03/05 全球购物
元旦寄语大全
2014/04/10 职场文书
赡养老人协议书
2014/04/21 职场文书
志愿者活动总结
2014/04/28 职场文书
三八节活动简报
2015/07/20 职场文书
教你使用Python pypinyin库实现汉字转拼音
2021/05/27 Python
mysqldump进行数据备份详解
2022/07/15 MySQL