thinkPHP3.0框架實現模板保存到數據庫的方法
本文實例講述了thinkPHP3.0框架實現模板保存到數據庫的方法。分享給大家供大家參考,具體如下:
在開發(fā)cms的時候用到如果將模板文件存入到數據庫并顯示到頁面中
由于thinkphp3.0都是直接從模板文件中讀取再解析的那么對于模板存入數據庫中就只有自己開發(fā)了,還有thinkphp3.0中有mode的功能我們可以定義自己的mode這樣就可以達到目的了,那么如何來擴展自己的mode呢?如下:
1.在你的入口文件中輸入
define('MODE_NAME','Ey');
其中"Ey"就是你自己擴展的mode名稱了,請在你的thinkphp/Extend/Mode文件下面創(chuàng)建Ey文件夾
2.在Ey目錄中修改
添加tags.php文件內容如下:
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的目錄中(由于解析內容,所以要修改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 { // 行為擴展的執(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 參數 //自動獲取模板文件 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', // 模板引擎禁用函數 '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'))// 優(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.添加自己解析模板內容的類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{ // 替換布局的主體內容 $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程序設計有所幫助。
相關文章
laravel框架模型中非靜態(tài)方法也能靜態(tài)調用的原理分析
這篇文章主要介紹了laravel框架模型中非靜態(tài)方法也能靜態(tài)調用的原理,結合實例形式分析了laravel模型基類中使用魔術方法實現非靜態(tài)方法進行靜態(tài)調用的相關原理,需要的朋友可以參考下2019-11-11tp5(thinkPHP5框架)使用DB實現批量刪除功能示例
這篇文章主要介紹了tp5(thinkPHP5框架)使用DB實現批量刪除功能,結合實例形式分析了thinkPHP5前端視圖界面數據交互及后臺使用DB處理數據庫刪除的相關操作技巧,需要的朋友可以參考下2019-05-05Swoole?webSocket消息服務系統(tǒng)壓力測試解析
這篇文章主要為大家介紹了Swoole?webSocket消息服務系統(tǒng)壓力測試解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03