本文實例講述了thinkPHP3.0框架實現(xiàn)模板保存到數(shù)據(jù)庫的方法。分享給大家供大家參考,具體如下:
在開發(fā)cms的時候用到如果將模板文件存入到數(shù)據(jù)庫并顯示到頁面中
由于thinkphp3.0都是直接從模板文件中讀取再解析的那么對于模板存入數(shù)據(jù)庫中就只有自己開發(fā)了,還有thinkphp3.0中有mode的功能我們可以定義自己的mode這樣就可以達到目的了,那么如何來擴展自己的mode呢?如下:
1.在你的入口文件中輸入
define('MODE_NAME','Ey');其中"Ey"就是你自己擴展的mode名稱了,請在你的thinkphp/Extend/Mode文件下面創(chuàng)建Ey文件夾
2.在Ey目錄中修改
添加tags.php文件內(nèi)容如下:
return array( 'app_init'=>array( ), 'app_begin'=>array( 'ReadHtmlCache', // 讀取靜態(tài)緩存 ), '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', // 寫入靜態(tài)緩存 'ShowRuntime', // 運行時間顯示 ), 'view_end'=>array( 'ShowPageTrace', // 頁面Trace顯示 ),);
該文件中后面的注釋中添加手動添加了為我的修改,只是修改thinkphp中默認的tags中查找模板和解析模板的行為
將系統(tǒng)默認的action和view類復制到Ey的目錄中(由于解析內(nèi)容,所以要修改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();    // 內(nèi)容過濾標簽    tag('view_filter',$content);    // 輸出模板文件    return $content;}	3.擴展自己的查找模板的類(自己擴展的行為tp讓我們放在thinkphp/Extend/Behavior中)
	在thinkphp/Extend/Behavior中添加ExtensionTemplateBehavior.class.php類,內(nèi)容如下:
class ExtensionTemplateBehavior extends Behavior {  // 行為擴展的執(zhí)行入口必須是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 參數(shù)      //自動獲取模板文件      if('' == $templateFile){        // 如果模板文件名為空 按照默認規(guī)則定位        $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 {          // 解析規(guī)則為 模板主題:模塊:操作 不支持 跨項目和跨分組調用          $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 {          // 解析規(guī)則為 模板主題:模塊:操作 不支持 跨項目和跨分組調用          $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', // 模板引擎禁用函數(shù)    'TMPL_DENY_PHP' =>false, // 默認模板引擎是否禁用PHP原生代碼    'TMPL_L_DELIM'     => '{',     // 模板引擎普通標簽開始標記    'TMPL_R_DELIM'     => '}',     // 模板引擎普通標簽結束標記    'TMPL_VAR_IDENTIFY'   => 'array',   // 模板變量識別。留空自動判斷,參數(shù)為'obj'則表示對象    'TMPL_STRIP_SPACE'   => true,    // 是否去除模板文件里面的html空格與換行    'TMPL_CACHE_ON'     => true,    // 是否開啟模板編譯緩存,設為false則每次都會重新編譯    'TMPL_CACHE_TIME'    =>  0,     // 模板緩存有效期 0 為永久,(以數(shù)字為值,單位:秒)    'TMPL_LAYOUT_ITEM'  =>  '{__CONTENT__}', // 布局模板的內(nèi)容替換標識    'LAYOUT_ON'      => false, // 是否啟用布局    'LAYOUT_NAME'    => 'layout', // 當前布局名稱 默認為layout    // Think模板引擎標簽庫相關設定    'TAGLIB_BEGIN'     => '<', // 標簽庫標簽開始標記    'TAGLIB_END'      => '>', // 標簽庫標簽結束標記    'TAGLIB_LOAD'      => true, // 是否使用內(nèi)置標簽庫之外的其它標簽庫,默認自動檢測    'TAGLIB_BUILD_IN'    => 'cx', // 內(nèi)置標簽庫名稱(標簽使用不必指定標簽庫名稱),以逗號分隔 注意解析順序    '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')) {          // 內(nèi)置驅動          $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'])){ //如果指定內(nèi)容          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'].']');          }        }        //這里文件和內(nèi)容一定有一個存在,否則在之前就會有異常了        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')) {            // 內(nèi)置驅動            $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')) {        // 內(nèi)置驅動        $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'))// 優(yōu)先對配置設定檢測      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.添加自己解析模板內(nèi)容的類TemplateEy.class.php(這個放在thinkphp/Extend/Driver/Template目錄下面)
	只是將系統(tǒng)默認的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{ // 替換布局的主體內(nèi)容          $layoutFile = THEME_PATH.C('LAYOUT_NAME').$this->config['template_suffix'];          $templateContent = str_replace($this->config['layout_item'],$templateContent,file_get_contents($layoutFile));        }      }      //編譯模板內(nèi)容      $templateContent = $this->compiler($templateContent);      extract($templateVar, EXTR_OVERWRITE);      echo $templateContent;    } else {      $templateCacheFile = $this->loadTemplate($templateFile,$templateContent);      // 模板陣列變量分解成為獨立變量      extract($templateVar, EXTR_OVERWRITE);      //載入模版緩存文件      include $templateCacheFile;    }}6.調用如果數(shù)據(jù)庫中模板的內(nèi)容不存在那么我們還是去讀數(shù)據(jù)庫中的內(nèi)容:
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框架的PHP程序設計有所幫助。
新聞熱點
疑難解答
圖片精選