thinkPHP3.0框架實現(xiàn)模板保存到數(shù)據(jù)庫的方法
本文實例講述了thinkPHP3.0框架實現(xiàn)模板保存到數(shù)據(jù)庫的方法。分享給大家供大家參考,具體如下:
在開發(fā)cms的時候用到如果將模板文件存入到數(shù)據(jù)庫并顯示到頁面中
由于thinkphp3.0都是直接從模板文件中讀取再解析的那么對于模板存入數(shù)據(jù)庫中就只有自己開發(fā)了,還有thinkphp3.0中有mode的功能我們可以定義自己的mode這樣就可以達(dá)到目的了,那么如何來擴(kuò)展自己的mode呢?如下:
1.在你的入口文件中輸入
define('MODE_NAME','Ey');
其中"Ey"就是你自己擴(kuò)展的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中默認(rèn)的tags中查找模板和解析模板的行為
將系統(tǒng)默認(rèn)的action和view類復(fù)制到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{
// 視圖解析標(biāo)簽
$params = array('var'=>$this->tVar,'content'=>$params['templateContent'],'file'=>$params['templateFile'],'cacheFlag'=>$params['cacheFlag']);
tag('view_content',$params);
}
// 獲取并清空緩存
$content = ob_get_clean();
// 內(nèi)容過濾標(biāo)簽
tag('view_filter',$content);
// 輸出模板文件
return $content;
}
3.擴(kuò)展自己的查找模板的類(自己擴(kuò)展的行為tp讓我們放在thinkphp\Extend\Behavior中)
在thinkphp\Extend\Behavior中添加ExtensionTemplateBehavior.class.php類,內(nèi)容如下:
class ExtensionTemplateBehavior extends Behavior {
// 行為擴(kuò)展的執(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'])) { // 是否設(shè)置 templateContent 參數(shù)
//自動獲取模板文件
if('' == $templateFile){
// 如果模板文件名為空 按照默認(rèn)規(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ī)則為 模板主題:模塊:操作 不支持 跨項目和跨分組調(diào)用
$action = array_pop($path);
$module = !empty($path)?array_pop($path):MODULE_NAME;
if(!empty($path)) {// 設(shè)置模板主題
$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ī)則為 模板主題:模塊:操作 不支持 跨項目和跨分組調(diào)用
$action = array_pop($path);
$module = !empty($path)?array_pop($path):MODULE_NAME;
if(!empty($path)) {// 設(shè)置模板主題
$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默認(rèn)的ParseTemplateBehavior.class.php類似)
class ParseContentBehavior extends Behavior {
protected $options = array(
// 布局設(shè)置
'TMPL_ENGINE_TYPE' => 'Ey', // 默認(rèn)模板引擎 以下設(shè)置僅對使用Ey模板引擎有效
'TMPL_CACHFILE_SUFFIX' => '.php', // 默認(rèn)模板緩存后綴
'TMPL_DENY_FUNC_LIST' => 'echo,exit', // 模板引擎禁用函數(shù)
'TMPL_DENY_PHP' =>false, // 默認(rèn)模板引擎是否禁用PHP原生代碼
'TMPL_L_DELIM' => '{', // 模板引擎普通標(biāo)簽開始標(biāo)記
'TMPL_R_DELIM' => '}', // 模板引擎普通標(biāo)簽結(jié)束標(biāo)記
'TMPL_VAR_IDENTIFY' => 'array', // 模板變量識別。留空自動判斷,參數(shù)為'obj'則表示對象
'TMPL_STRIP_SPACE' => true, // 是否去除模板文件里面的html空格與換行
'TMPL_CACHE_ON' => true, // 是否開啟模板編譯緩存,設(shè)為false則每次都會重新編譯
'TMPL_CACHE_TIME' => 0, // 模板緩存有效期 0 為永久,(以數(shù)字為值,單位:秒)
'TMPL_LAYOUT_ITEM' => '{__CONTENT__}', // 布局模板的內(nèi)容替換標(biāo)識
'LAYOUT_ON' => false, // 是否啟用布局
'LAYOUT_NAME' => 'layout', // 當(dāng)前布局名稱 默認(rèn)為layout
// Think模板引擎標(biāo)簽庫相關(guān)設(shè)定
'TAGLIB_BEGIN' => '<', // 標(biāo)簽庫標(biāo)簽開始標(biāo)記
'TAGLIB_END' => '>', // 標(biāo)簽庫標(biāo)簽結(jié)束標(biāo)記
'TAGLIB_LOAD' => true, // 是否使用內(nèi)置標(biāo)簽庫之外的其它標(biāo)簽庫,默認(rèn)自動檢測
'TAGLIB_BUILD_IN' => 'cx', // 內(nèi)置標(biāo)簽庫名稱(標(biāo)簽使用不必指定標(biāo)簽庫名稱),以逗號分隔 注意解析順序
'TAGLIB_PRE_LOAD' => '', // 需要額外加載的標(biāo)簽庫(須指定標(biāo)簽庫名稱),多個以逗號分隔
);
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)置驅(qū)動
$path = CORE_PATH;
} else {
// 擴(kuò)展驅(qū)動
$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)置驅(qū)動
$path = CORE_PATH;
} else {
// 擴(kuò)展驅(qū)動
$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 {
//調(diào)用第三方模板引擎解析和輸出
$class = 'Template'.ucwords($engine);
if(is_file(CORE_PATH.'Driver/Template/'.$class.'.class.php')) {
// 內(nèi)置驅(qū)動
$path = CORE_PATH;
}else{ // 擴(kuò)展驅(qū)動
$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)先對配置設(shè)定檢測
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)默認(rèn)的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.調(diào)用如果數(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");
}
更多關(guān)于thinkPHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《ThinkPHP入門教程》、《thinkPHP模板操作技巧總結(jié)》、《ThinkPHP常用方法總結(jié)》、《codeigniter入門教程》、《CI(CodeIgniter)框架進(jìn)階教程》、《Zend FrameWork框架入門教程》及《PHP模板技術(shù)總結(jié)》。
希望本文所述對大家基于ThinkPHP框架的PHP程序設(shè)計有所幫助。
相關(guān)文章
laravel框架模型中非靜態(tài)方法也能靜態(tài)調(diào)用的原理分析
這篇文章主要介紹了laravel框架模型中非靜態(tài)方法也能靜態(tài)調(diào)用的原理,結(jié)合實例形式分析了laravel模型基類中使用魔術(shù)方法實現(xiàn)非靜態(tài)方法進(jìn)行靜態(tài)調(diào)用的相關(guān)原理,需要的朋友可以參考下2019-11-11
PHP 超高性能可擴(kuò)展HTTP服務(wù)框架Webman
本文主要介紹了超高性能可擴(kuò)展HTTP服務(wù)框架Webman,webman用于替代傳統(tǒng)的php-fpm架構(gòu),提供超高性能可擴(kuò)展的HTTP服務(wù),感興趣的可以了解一下2024-02-02
win7計劃任務(wù)定時執(zhí)行PHP腳本設(shè)置圖解
這篇文章主要介紹了win7計劃任務(wù)定時執(zhí)行PHP腳本設(shè)置圖解,需要的朋友可以參考下2014-05-05
tp5(thinkPHP5框架)使用DB實現(xiàn)批量刪除功能示例
這篇文章主要介紹了tp5(thinkPHP5框架)使用DB實現(xiàn)批量刪除功能,結(jié)合實例形式分析了thinkPHP5前端視圖界面數(shù)據(jù)交互及后臺使用DB處理數(shù)據(jù)庫刪除的相關(guān)操作技巧,需要的朋友可以參考下2019-05-05
Swoole?webSocket消息服務(wù)系統(tǒng)壓力測試解析
這篇文章主要為大家介紹了Swoole?webSocket消息服務(wù)系統(tǒng)壓力測試解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03

