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

网络编程 PHP编程 php实例 分类:[default] 更新日期: 2016-12-17
这篇文章主要介绍了thinkPHP3.0框架实现模板保存到数据库的方法,结合实例形式分析了使用thinkPHP3.0框架开发CMS系统过程中将模板保存到数据库的具体实现步骤与相关操作技巧,需要的朋友可以参考下

本文实例讲述了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程序设计有所帮助。


> 本站内容系网友提交或本网编辑转载,其目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请及时与本网联系,我们将在第一时间删除内容!

相关文章
  • 将PHP的session数据存储到数据库中的代码实例
    这里我们将分享两个将PHP的session数据存储到数据库中的代码实例,分别针对PostgreSQL与MySQL,需要的朋友可以参考下一个开发环境有多个网站,需要使用不同的session,解决方案很多.不过这次也高大上一把,用数据库存,方便以后扩展. PostgreSQL版首先是数据库的部分 --drop table php_session create u ...
  • Web2.0编程思想:16条法则
    1.在你开始之前,先定一个简单的目标.无论你是一个Web 2.0应用的创建者还是用户,请清晰的构思你的目标.就像"我需要保存一个书签"或者"我准备帮助人们创建可编辑的.共享的页面"这样的目标,让你保持最基础的需求.很多Web 2.0应用的最初吸引之处就是它的简单,避免并隐藏了那些多余的复杂性.站在创建者的立场,可以想象 ...
  • 将xml文件作为一个小的数据库,进行学生的增删改查的简单实例
    下面小编就为大家带来一篇将xml文件作为一个小的数据库,进行学生的增删改查的简单实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧1.xml文件: <?xml version="1.0" encoding="UTF-8"?><Students> <stude ...
  • PHP生成静态HTML文档实现代码
    这篇文章主要为大家详细介绍了PHP生成静态HTML文档实现代码,将数据库中的文章数据生成单个的HTML文档原理,感兴趣的小伙伴们可以参考一下利用PHP,将数据库中的文章数据生成单个的HTML文档.首先,有利于搜索引擎的收录.其次,避免数据库中的字段暴露在地址栏上,更安全. 给出代码: <?php //引入数据库配置文件 include( dirname ...
  • php项目开发中用到的快速排序算法分析
    这篇文章主要介绍了php项目开发中用到的快速排序算法,结合实例形式详细分析了php快速排序的原理与使用方法,需要的朋友可以参考下本文实例讲述了php项目开发中用到的快速排序算法.分享给大家供大家参考,具体如下: 实际上在,做web开发,比较少遇到使用一些算法之类的,毕竟不是做搜索引擎,也不是写底层(比如写个类似于mysql这样的数据库,里面需要自己实现排序算 ...
  • MongoDB的Master-Slave主从模式配置及主从复制要点解析
    主从复制是数据库运维中一种常见的备份方式,这里我们来看一下MongoDB的Master-Slave主从模式配置及主从复制要点解析,需要的朋友可以参考下主从配置mongodb的master-slave模式配置方式如下1.keyFile生成key_file openssl rand -base64 741 > mongo_key 将mongo_key 分别 ...
猜你喜欢