thinkPHP3.0框架实现模板保存到数据库的方法

发布时间 - 2026-01-11 02:54:19    点击率:

本文实例讲述了thinkPHP3.0框架实现模板保存到数据库的方法。分享给大家供大家参考,具体如下:

在开发cms的时候用到如果将模板文件存入到数据库并显示到页面中

由于thinkphp3.0都是直接从模板文件中读取再解析的那么对于模板存入数据库中就只有自己开发了,还有thinkphp3.0中有mode的功能我们可以定义自己的mode这样就可以达到目的了,那么如何来扩展自己的mode呢?如下:

1.在你的入口文件中输入

define('MODE_NAME','Ey');

其中"Ey"就是你自己扩展的mode名称了,请在你的thinkphp/Extend/Mode文件下面创建Ey文件夹

2.在Ey目录中修改

添加tags.php文件内容如下:

return array(
  'app_init'=>array(
  ),
  'app_begin'=>array(
    'ReadHtmlCache', // 读取静态缓存
  ),
  'route_check'=>array(
    'CheckRoute', // 路由检测
  ),
  'app_end'=>array(),
  'path_info'=>array(),
  'action_begin'=>array(),
  'action_end'=>array(),
  'view_begin'=>array(),
  'view_template'=>array(
    'ExtensionTemplate', // 自动定位模板文件(手动添加)
  ),
  'view_content'=>array(
    'ParseContent'//(手动添加)
  ),
  'view_filter'=>array(
    'ContentReplace', // 模板输出替换
    'TokenBuild',  // 表单令牌
    'WriteHtmlCache', // 写入静态缓存
    'ShowRuntime', // 运行时间显示
  ),
  'view_end'=>array(
    'ShowPageTrace', // 页面Trace显示
  ),
);

该文件中后面的注释中添加手动添加了为我的修改,只是修改thinkphp中默认的tags中查找模板和解析模板的行为

将系统默认的action和view类复制到Ey的目录中(由于解析内容,所以要修改action和view类),修改action.class.php中的fetch方法:

protected function fetch($templateFile='',$templateContent='' ){
    return $this->view->fetch($templateFile,$templateContent);
}

view.class.php文件中的修改为:

public function fetch($templateFile='',$templateContent = NULL) {
    $params['templateFile'] = $templateFile;
    $params['cacheFlag'] = true;
    if(isset($templateContent)) {
      $params['templateContent'] = $templateContent;
    }
    tag('view_template',$params);
    // 页面缓存
    ob_start();
    ob_implicit_flush(0);
    if('php' == strtolower(C('TMPL_ENGINE_TYPE'))) { // 使用PHP原生模板
      // 模板阵列变量分解成为独立变量
      extract($this->tVar, EXTR_OVERWRITE);
      // 直接载入PHP模板
      include $templateFile;
    }else{
      // 视图解析标签
      $params = array('var'=>$this->tVar,'content'=>$params['templateContent'],'file'=>$params['templateFile'],'cacheFlag'=>$params['cacheFlag']);
      tag('view_content',$params);
    }
    // 获取并清空缓存
    $content = ob_get_clean();
    // 内容过滤标签
    tag('view_filter',$content);
    // 输出模板文件
    return $content;
}

3.扩展自己的查找模板的类(自己扩展的行为tp让我们放在thinkphp\Extend\Behavior中)
在thinkphp\Extend\Behavior中添加ExtensionTemplateBehavior.class.php类,内容如下:

class ExtensionTemplateBehavior extends Behavior {
  // 行为扩展的执行入口必须是run
  public function run(&$params){
    if( is_array($params) ){
      if( array_key_exists('templateFile', $params) ){
        $params  = $this->parseTemplateFile($params);
      }else{
        //异常
        throw_exception(L('_TEMPLATE_NOT_EXIST_AND_CONTENT_NULL_').'['.$params['templateFile'].']');
      }
    }else{
      // 自动定位模板文件
      if(!file_exists_case($params))
        $params  = $this->parseTemplateFile($params);
    }
  }
  private function parseTemplateFile($params) {
    if( is_array($params) ) {
      $templateFile = $params['templateFile'];
    }else{
      $templateFile = $params;
    }
    if(!isset($params['templateContent'])) { // 是否设置 templateContent 参数
      //自动获取模板文件
      if('' == $templateFile){
        // 如果模板文件名为空 按照默认规则定位
        $templateFile = C('TEMPLATE_NAME');
      } elseif(false === strpos($templateFile,C('TMPL_TEMPLATE_SUFFIX'))) {
        $path  = explode(':',$templateFile);
        //如果是插件
        if($path[0] == 'Ext') {
          $templateFile = str_replace(array('Ext:',$path[1] . ':',$path[2] . ':'),'',$templateFile);
          $templateFile = SITE_ROOT . '/Ext/extensions/' . strtolower($path[1]) . '/' . $path[2] . '/Tpl/' . $templateFile . C('TMPL_TEMPLATE_SUFFIX');
        } else {
          // 解析规则为 模板主题:模块:操作 不支持 跨项目和跨分组调用
          $action = array_pop($path);
          $module = !empty($path)?array_pop($path):MODULE_NAME;
          if(!empty($path)) {// 设置模板主题
            $path = dirname(THEME_PATH).'/'.array_pop($path).'/';
          }else{
            $path = THEME_PATH;
          }
          $depr = defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/';
          $templateFile = $path.$module.$depr.$action.C('TMPL_TEMPLATE_SUFFIX');
        }
      }
    } else {
      if('' == $templateFile){
        $depr = defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/';
        $params['cacheFlag'] = false;
      } else {
        $path  = explode(':',$templateFile);
        //如果是插件
        if($path[0] == 'Ext') {
          $templateFile = str_replace(array('Ext:',$path[1] . ':',$path[2] . ':'),'',$templateFile);
          $templateFile = SITE_ROOT . '/Ext/extensions/' . strtolower($path[1]) . '/' . $path[2] . '/Tpl/' . $templateFile . C('TMPL_TEMPLATE_SUFFIX');
        } else {
          // 解析规则为 模板主题:模块:操作 不支持 跨项目和跨分组调用
          $action = array_pop($path);
          $module = !empty($path)?array_pop($path):MODULE_NAME;
          if(!empty($path)) {// 设置模板主题
            $path = dirname(THEME_PATH).'/'.array_pop($path).'/';
          }else{
            $path = THEME_PATH;
          }
          $depr = defined('GROUP_NAME')?C('TMPL_FILE_DEPR'):'/';
          $templateFile = $path.$module.$depr.$action.C('TMPL_TEMPLATE_SUFFIX');
        }
      }
    }
    if( is_array($params) ){
      $params['templateFile'] = $templateFile;
      return $params;
    }else{
      if(!file_exists_case($templateFile))
        throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$templateFile.']');
      return $templateFile;
    }
  }
}

4.添加解析自己的模板的行为类(这个和thinkphp3.0默认的ParseTemplateBehavior.class.php类似)

class ParseContentBehavior extends Behavior {
  protected $options  = array(
    // 布局设置
    'TMPL_ENGINE_TYPE'   => 'Ey',   // 默认模板引擎 以下设置仅对使用Ey模板引擎有效
    'TMPL_CACHFILE_SUFFIX' => '.php',   // 默认模板缓存后缀
    'TMPL_DENY_FUNC_LIST'  => 'echo,exit', // 模板引擎禁用函数
    'TMPL_DENY_PHP' =>false, // 默认模板引擎是否禁用PHP原生代码
    'TMPL_L_DELIM'     => '{',     // 模板引擎普通标签开始标记
    'TMPL_R_DELIM'     => '}',     // 模板引擎普通标签结束标记
    'TMPL_VAR_IDENTIFY'   => 'array',   // 模板变量识别。留空自动判断,参数为'obj'则表示对象
    'TMPL_STRIP_SPACE'   => true,    // 是否去除模板文件里面的html空格与换行
    'TMPL_CACHE_ON'     => true,    // 是否开启模板编译缓存,设为false则每次都会重新编译
    'TMPL_CACHE_TIME'    =>  0,     // 模板缓存有效期 0 为永久,(以数字为值,单位:秒)
    'TMPL_LAYOUT_ITEM'  =>  '{__CONTENT__}', // 布局模板的内容替换标识
    'LAYOUT_ON'      => false, // 是否启用布局
    'LAYOUT_NAME'    => 'layout', // 当前布局名称 默认为layout
    // Think模板引擎标签库相关设定
    'TAGLIB_BEGIN'     => '<', // 标签库标签开始标记
    'TAGLIB_END'      => '>', // 标签库标签结束标记
    'TAGLIB_LOAD'      => true, // 是否使用内置标签库之外的其它标签库,默认自动检测
    'TAGLIB_BUILD_IN'    => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序
    'TAGLIB_PRE_LOAD'    => '',  // 需要额外加载的标签库(须指定标签库名称),多个以逗号分隔
    );
  public function run(&$_data){
    $engine = strtolower(C('TMPL_ENGINE_TYPE'));
    //这个地方要判断是否存在文件
    if('think'==$engine){
      if($this->checkCache($_data['file'])) { // 缓存有效
        // 分解变量并载入模板缓存
        extract($_data['var'], EXTR_OVERWRITE);
        //载入模版缓存文件
        include C('CACHE_PATH').md5($_data['file']).C('TMPL_CACHFILE_SUFFIX');
      }else{
        $tpl = Think::instance('ThinkTemplate');
        // 编译并加载模板文件
        $tpl->fetch($_data['file'],$_data['var']);
      }
    } else if('ey' == $engine) {
      if( !$_data['cacheFlag'] ){
        $class  = 'Template'.ucwords($engine);
        if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {
          // 内置驱动
          $path = CORE_PATH;
        } else {
          // 扩展驱动
          $path = EXTEND_PATH;
        }
        if(require_cache($path.'Driver/Template/'.$class.'.class.php')) {
          $tpl  = new $class;
          $tpl->fetch('',$_data['content'],$_data['var']);
        } else { // 类没有定义
          throw_exception(L('_NOT_SUPPERT_').': ' . $class);
        }
      }else{
        //操作
        $cache_flag = true;
        if(isset($_data['content'])){ //如果指定内容
          if ($_data['file']){ //指定缓存KEY
            $_data['file'] = 'custom_' . $_data['file'];
          } else { //未指定缓存KEY,则不缓存
            $cache_flag = false;
          }
        } else {
          if (is_file($_data['file'])){ //如果指定文件存在
            $_data['content'] = file_get_contents($_data['file']);
          } else {
            throw_exception(L('_TEMPLATE_NOT_EXIST_').'['.$_data['file'].']');
          }
        }
        //这里文件和内容一定有一个存在,否则在之前就会有异常了
        if($cache_flag && $this->checkCache($_data['file'],$_data['content']) ) { // 缓存有效
          // 分解变量并载入模板缓存
          extract($_data['var'], EXTR_OVERWRITE);
          //载入模版缓存文件
          include C('CACHE_PATH').md5($_data['file']).C('TMPL_CACHFILE_SUFFIX');
        } else {
          $class  = 'Template'.ucwords($engine);
          if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {
            // 内置驱动
            $path = CORE_PATH;
          } else {
            // 扩展驱动
            $path = EXTEND_PATH;
          }
          if(require_cache($path.'Driver/Template/'.$class.'.class.php')) {
            $tpl  = new $class;
            $tpl->fetch($_data['file'],$_data['content'],$_data['var']);
          } else { // 类没有定义
            throw_exception(L('_NOT_SUPPERT_').': ' . $class);
          }
        }
      }
    } else {
      //调用第三方模板引擎解析和输出
      $class  = 'Template'.ucwords($engine);
      if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {
        // 内置驱动
        $path = CORE_PATH;
      }else{ // 扩展驱动
        $path = EXTEND_PATH;
      }
      if(require_cache($path.'Driver/Template/'.$class.'.class.php')) {
        $tpl  = new $class;
        $tpl->fetch($_data['file'],$_data['var']);
      }else { // 类没有定义
        throw_exception(L('_NOT_SUPPERT_').': ' . $class);
      }
    }
  }
  protected function checkCache($tmplTemplateFile = '',$tmplTemplateContent='') {
    if (!C('TMPL_CACHE_ON'))// 优先对配置设定检测
      return false;
    //缓存文件名
    $tmplCacheFile = C('CACHE_PATH').md5($tmplTemplateFile).C('TMPL_CACHFILE_SUFFIX');
    if(!is_file($tmplCacheFile)){
      return false;
    }elseif (filemtime($tmplTemplateFile) > filemtime($tmplCacheFile)) {
      // 模板文件如果有更新则缓存需要更新
      return false;
    }elseif (C('TMPL_CACHE_TIME') != 0 && time() > filemtime($tmplCacheFile)+C('TMPL_CACHE_TIME')) {
      // 缓存是否在有效期
      return false;
    }
    // 开启布局模板
    if(C('LAYOUT_ON')) {
      $layoutFile = THEME_PATH.C('LAYOUT_NAME').C('TMPL_TEMPLATE_SUFFIX');
      if(filemtime($layoutFile) > filemtime($tmplCacheFile)) {
        return false;
      }
    }
    // 缓存有效
    return true;
  }
}

5.添加自己解析模板内容的类TemplateEy.class.php(这个放在thinkphp\Extend\Driver\Template目录下面)
只是将系统默认的ThinkTemplate.class.php类修改了fetch方法修改代码如下:

// 加载模板
public function fetch($templateFile,$templateContent,$templateVar) {
    $this->tVar = $templateVar;
    if($templateContent && !$templateFile) { //不缓存
      if(C('LAYOUT_ON')) {
        if(false !== strpos($templateContent,'{__NOLAYOUT__}')) { // 可以单独定义不使用布局
          $templateContent = str_replace('{__NOLAYOUT__}','',$templateContent);
        }else{ // 替换布局的主体内容
          $layoutFile = THEME_PATH.C('LAYOUT_NAME').$this->config['template_suffix'];
          $templateContent = str_replace($this->config['layout_item'],$templateContent,file_get_contents($layoutFile));
        }
      }
      //编译模板内容
      $templateContent = $this->compiler($templateContent);
      extract($templateVar, EXTR_OVERWRITE);
      echo $templateContent;
    } else {
      $templateCacheFile = $this->loadTemplate($templateFile,$templateContent);
      // 模板阵列变量分解成为独立变量
      extract($templateVar, EXTR_OVERWRITE);
      //载入模版缓存文件
      include $templateCacheFile;
    }
}

6.调用如果数据库中模板的内容不存在那么我们还是去读数据库中的内容:

if( array_key_exists( $display_mode, $params['tpl'] ) && strlen($params['tpl'][$display_mode]) > 0 ){
return $this->fetch("Ext:New:Frontend:show",$params['tpl'][$display_mode]);
}else{
return $this->fetch("Ext:New:Frontend:show");
}

更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《Zend FrameWork框架入门教程》及《PHP模板技术总结》。

希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。


# thinkPHP3.0  # 模板  # 保存  # 数据库  # thinkphp3.0 模板中函数的使用  # ThinkPHP3.0略缩图不能保存到子目录的解决方法  # thinkPHP的Html模板标签使用方法  # ThinkPHP跳转页success及error模板实例教程  # ThinkPHP模板之变量输出、自定义函数与判断语句用法  # ThinkPHP模板自定义标签使用方法  # ThinkPHP模板输出display用法分析  # 浅析ThinkPHP的模板输出功能  # thinkphp模板继承实例简述  # thinkphp配置连接数据库技巧  # thinkPHP数据库增删改查操作方法实例详解  # 自己的  # 放在  # 加载  # 不支持  # 都是  # 进阶  # 相关内容  # 让我们  # 多个  # 令牌  # 中有  # 目录中  # 设为  # 你自己  # 感兴趣  # 请在  # 我们可以  # 给大家  # 不存在  # 就可 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 软银砸40亿美元收购DigitalBridge 强化AI资料中心布局  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  详解jQuery中的事件  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  Angular 表单中正确绑定输入值以确保提交与验证正常工作  七夕网站制作视频,七夕大促活动怎么报名?  Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  使用豆包 AI 辅助进行简单网页 HTML 结构设计  Python函数文档自动校验_规范解析【教程】  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  用yum安装MySQLdb模块的步骤方法  教你用AI润色文章,让你的文字表达更专业  简单实现jsp分页  Laravel事件监听器怎么写_Laravel Event和Listener使用教程  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  Laravel如何使用Gate和Policy进行授权?(权限控制)  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  JavaScript模板引擎Template.js使用详解  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  微信小程序 require机制详解及实例代码  Laravel如何使用withoutEvents方法临时禁用模型事件  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  java ZXing生成二维码及条码实例分享  活动邀请函制作网站有哪些,活动邀请函文案?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  如何快速配置高效服务器建站软件?  如何破解联通资金短缺导致的基站建设难题?  标题:Vue + Vuex 项目中正确使用 JWT 进行身份认证的实践指南  如何选择PHP开源工具快速搭建网站?  购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?  标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析  jimdo怎样用html5做选项卡_jimdo选项卡html5实现与切换效果【指南】  zabbix利用python脚本发送报警邮件的方法  浅谈redis在项目中的应用  nginx修改上传文件大小限制的方法  Python并发异常传播_错误处理解析【教程】  东莞市网站制作公司有哪些,东莞找工作用什么网站好?  如何在企业微信快速生成手机电脑官网?  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  Thinkphp 中 distinct 的用法解析  黑客如何利用漏洞与弱口令入侵网站服务器?