PHPCMS2008原始碼模板原理分析
 

<?php
PHPCMS2008模版原理篇

一、config.inc.php 裡面關於模版的相關配置變數

//模板相關配置
define(`TPL_ROOT`, PHPCMS_ROOT.`templates/`); //模板儲存物理路徑
define(`TPL_NAME`, `default`); //當前模板方案目錄
define(`TPL_CSS`, `default`); //當前樣式目錄
define(`TPL_CACHEPATH`, PHPCMS_ROOT.`data/cache_template/`); //模板快取物理路徑
define(`TPL_REFRESH`, 1); //是否開啟模板快取自動重新整理

二、global.func.php 的相關呼叫函式

function template($module = `phpcms`, $template = `index`, $istag = 0)    //模版呼叫函式(模組名,模版名,是否tag)
{
$compiledtplfile = TPL_CACHEPATH.$module.`_`.$template.`.tpl.php`;       //根據引數生成cache模板php檔案
if(TPL_REFRESH && (!file_exists($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.`/`.$module.`/`.$template.`.html`) > @filemtime($compiledtplfile) || @filemtime(TPL_ROOT.TPL_NAME.`/tag.inc.php`) > @filemtime($compiledtplfile)))
//判斷模版生成檔案是否過期,或不存在,否則重新生成
{
require_once PHPCMS_ROOT.`include/template.func.php`; //呼叫模版函式
template_compile($module, $template, $istag);          //生成最新模版相關檔案
}
return $compiledtplfile;                                //返回模板生成檔案.php檔案
}

function tpl_data($module = `phpcms`, $template = `index`)   //生成tpl的資料模板
{
@extract($GLOBALS, EXTR_SKIP);
ob_start();
include template($module, $template);
$data = ob_get_contents();
ob_clean();
return $data;
}

三、template.func.php 的相關函式
<?php
function template_compile($module, $template, $istag = 0)
{
$tplfile = TPL_ROOT.TPL_NAME.`/`.$module.`/`.$template.`.html`;   //生成模版名
$content = @file_get_contents($tplfile);                          //載入模版檔案
if($content === false) showmessage(“$tplfile is not exists!”);
$compiledtplfile = TPL_CACHEPATH.$module.`_`.$template.`.tpl.php`; //生成模版cache檔名
$content = ($istag || substr($template, 0, 4) == `tag_`) ? `<?php function _tag_`.$module.`_`.$template.`($data, $number, $rows, $count, $page, $pages, $setting){ global $PHPCMS,$MODULE,$M,$CATEGORY,$TYPE,$AREA,$GROUP,$MODEL,$templateid,$_userid,$_username;@extract($setting);?>`.template_parse($content, 1).`<?php } ?>` : template_parse($content);
//用template_parse正則替換後,形成可以執行的php檔案
$strlen = file_put_contents($compiledtplfile, $content); //寫到cache裡
@chmod($compiledtplfile, 0777);
return $strlen;                       //返回生成值
}

function template_refresh($tplfile, $compiledtplfile)   //單個模版檔案的更新
{
$str = file_get_contents($tplfile);
$str = template_parse($str);
$strlen = file_put_contents($compiledtplfile, $str);
@chmod($compiledtplfile, 0777);
return $strlen;
}

function template_module($module)                              //更新一個模組的所有快取檔案
{
$files = glob(TPL_ROOT.TPL_NAME.`/`.$module.`/*.html`);    //徵收成檔名陣列
if(is_array($files))
{
foreach($files as $tpl)
{
$template = str_replace(`.html`, “, basename($tpl));   //正則取檔名,去掉.html
template_compile($module, $template);                  //重新生成module的cache
}
}
return TRUE;
}

function template_cache()                         //生成所能的模組cache檔案
{
global $MODULE;                               //全域性變數module 可能是呼叫的cache.func生成的檔案下的變數引入的,暫時沒明,下回分解
foreach($MODULE as $module=>$m)
{
template_module($module);
}
return TRUE;
}

function template_block($blockid)                  
{
$tplfile = TPL_ROOT.TPL_NAME.`/phpcms/block/`.$blockid.`.html`;
$compiledtplfile = TPL_CACHEPATH.`phpcms_block_`.$blockid.`.tpl.php`;
if(TPL_REFRESH && (!file_exists($compiledtplfile) || @filemtime($tplfile) > @filemtime($compiledtplfile)))
{
template_refresh($tplfile, $compiledtplfile);
}
return $compiledtplfile;
}

function template_parse($str, $istag = 0)     
//此函式的最終目地是將,模版檔案.html檔案,形成/daba/data_templete/module_name.tpl.php 檔案,也就是一些正則的轉換,和dz的模式差不多
{
$str = preg_replace(“/([

]+) +/s”,”\1″,$str);
$str = preg_replace(“/<!–{(.+?)}–>/s”, “{\1}”,$str);
$str = preg_replace(“/{templates+(.+)}/”,”<?php include template(\1); ?>”,$str);
$str = preg_replace(“/{includes+(.+)}/”,”<?php include \1; ?>”,$str);
$str = preg_replace(“/{phps+(.+)}/”,”<?php \1?>”,$str);
$str = preg_replace(“/{ifs+(.+?)}/”,”<?php if(\1) { ?>”,$str);
$str = preg_replace(“/{else}/”,”<?php } else { ?>”,$str);
$str = preg_replace(“/{elseifs+(.+?)}/”,”<?php } elseif (\1) { ?>”,$str);
$str = preg_replace(“/{/if}/”,”<?php } ?>”,$str);
$str = preg_replace(“/{loops+(S+)s+(S+)}/”,”<?php if(is_array(\1)) foreach(\1 AS \2) { ?>”,$str);
$str = preg_replace(“/{loops+(S+)s+(S+)s+(S+)}/”,”<?php if(is_array(\1)) foreach(\1 AS \2 => \3) { ?>”,$str);
$str = preg_replace(“/{/loop}/”,”<?php } ?>”,$str);
$str = preg_replace(“/{/get}/”,”<?php } unset($DATA); ?>”,$str);
$str = preg_replace(“/{tag_([^}]+)}/e”, “get_tag(`\1`)”, $str);
$str = preg_replace(“/{gets+([^}]+)}/e”, “get_parse(`\1`)”, $str);
$str = preg_replace(“/{([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff:]*(([^{}]*)))}/”,”<?php echo \1;?>”,$str);
$str = preg_replace(“/{\$([a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff:]*(([^{}]*)))}/”,”<?php echo \1;?>”,$str);
$str = preg_replace(“/{(\$[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*)}/”,”<?php echo \1;?>”,$str);
$str = preg_replace(“/{(\$[a-zA-Z0-9_[]`”$x7f-xff]+)}/es“, “addquote(`<?php echo \1;?>`)”,$str);
$str = preg_replace(“/{([A-Z_x7f-xff][A-Z0-9_x7f-xff]*)}/s”, “<?php echo \1;?>”,$str);
if(!$istag) $str = “<?php defined(`IN_PHPCMS`) or exit(`Access Denied`); ?>”.$str;
return $str;
}

function get_tag($tagname)   //獲取phpcms的tag資料
{
global $TAG;
if(!isset($TAG)) $TAG = cache_read(`tag.inc.php`, TPL_ROOT.TPL_NAME.`/`);
return isset($TAG[$tagname]) ? `<?php echo `.$TAG[$tagname].`;?>` : `{tag_`.$tagname.`}`;
}

function addquote($var)          //變數資料加雙相號
{
return str_replace(“\“”, “””, preg_replace(“/[([a-zA-Z0-9_-.x7f-xff]+)]/s”, “[`\1`]”, $var));
}

function get_parse($str) //正則匹配
{
preg_match_all(“/([a-z]+)=”([^”]+)”/i”, stripslashes($str), $matches, PREG_SET_ORDER);
foreach($matches as $v)
{
$r[$v[1]] = $v[2];
}
extract($r);
if(!isset($dbsource)) $dbsource = “;
if(!isset($dbname)) $dbname = “;
if(!isset($sql)) $sql = “;
if(!isset($rows)) $rows = 0;
if(!isset($return) || !preg_match(“/^w+$/i”, $return)) $return = `r`;
if(isset($page))
{
$str = “<?php $ARRAY = get(“$sql”, $rows, $page, “$dbname”, “$dbsource”);$DATA=$ARRAY[`data`];$total=$ARRAY[`total`];$count=$ARRAY[`count`];$pages=$ARRAY[`pages`];unset($ARRAY);foreach($DATA AS $n=>${$return}){$n++;?>”;
}
else
{
$str = substr($str, -1) == `/` ? “<?php ${$return} = get(“$sql”, -1, 0, “$dbname”, “$dbsource”);?>” : “<?php $DATA = get(“$sql”, $rows, 0, “$dbname”, “$dbsource”);foreach($DATA AS $n => ${$return}) { $n++;?>”;
}
return $str;
}
?>

以上這些就是phpcms的預設檔案cache模版的生成原理

現看一下首頁的呼叫

<?php
………

include template(`phpcms`, `index`);   //載入進來,就是我們看到的首頁了,也就是載入了 /dada/cache_templete/phpcms_index.tpl.php
…….
?>