phpcms 源碼解析——-模板引擎

來源:互聯網
上載者:User

簡介:這是phpcms 源碼解析-------模板引擎的詳細頁面,介紹了和php,phpcms, php phpcms 源碼解析-------模板引擎有關的知識、技巧、經驗,和一些php源碼等。

class='pingjiaF' frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=357338' scrolling='no'>
PHPCMS 整站程式碼分析講解(六)之模板引擎

發布:水水

19 May

<?php

/**

函數 template函數是在global.func.php 裡面定義的。 在前面的phpcms 的首頁 index.php 裡就見到了。  用法: include template()    用法很熟, 呵呵其實和 dz 的模板引擎一樣的用法。 但DZ的模板引擎比 PHPCMS 的簡單很多,因為沒有用到模板的標籤技術。 大家有空可以研究下DZ的模板引擎。這裡不說。  好分析下上面這個 模板的主要函數吧。  他的作用是返回編譯好的模板檔案路徑。也就是把模板 X.html(模板檔案) 用正則替換成 x.php(編譯後的PHP檔案).然後使用 include  函數。懂了吧! php的模板引擎都一個鳥樣。 然後剩下的就是正則的東西了。等下再說。

*/

function template($module = 'phpcms', $template = 'index')

{

global $CONFIG;

$compiledtplfile = $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';

/**

因為phpcms是分模組來存放模板檔案。所以 template 函數有兩個參數: 第一個就是模組目錄名,第二個就是此模組裡面的模板檔案名稱.

$CONFIG['templatescachedir']  這個是放編譯後php檔案存放的目錄。在config.inc.php 網站設定檔裡面定義的自己去看。 這樣就取得了模板編譯後的php檔案路徑。

*/

if($CONFIG['templaterefresh']) //$CONFIG['templaterefresh']  在 config.inc.php裡面配置了。預設是1  。是更新模板開關。如果你設定為0 那麼模板更新了。程式也不會更新。

{

        $tplfile = PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html';

  /**

  和上面那句意思差不多。$CONFIG['defaulttemplate'] 是預設範本目錄  。這句是擷取你要的那個模組和裡面的那個模板檔案的路徑(@@擷取沒編譯前的模板檔案)

  */

        if(!file_exists($compiledtplfile) || @filemtime($tplfile) > @filemtime($compiledtplfile))

  {

   /**

   我把檔案編譯成了php檔案。那麼模板改變了。 php檔案總得也改變吧。要不你修改了模板後。站還是以前那個樣子沒變那有什麼意思呢。

   首先判斷模板編譯檔案是否存在。如果不存在那麼後邊那個條件不用判斷了。 因為編譯檔案都不存在。程式肯定運行不了拉。(因為其實我們主要是運行編譯後的那個php檔案,模板檔案是html的運行個P呀)

   或  後邊那個 @filemtime($tplfile) > @filemtime($compiledtplfile)  很容易就明白:  函數 filetime() 判斷檔案最近修改的時間,返回Unix 時間戳記。 如果模板檔案的修改時間 大於 編譯檔案。 那麼證明 模板檔案  在 編譯檔案產生後 還進行了修改。那麼我們是不是還要在更新次編譯檔案呀 ,那是肯定的拉。 所以繼續執行下去。

   */

   require_once PHPCMS_ROOT.'/include/template.func.php';   // 載入編譯函數

   template_refresh($tplfile, $compiledtplfile);// 這個就是模板的 編譯啟動函數 ,帶動一系列的模板編譯函數來最終產生模板編譯檔案。

  }

}

return $compiledtplfile; // 返回 模板編譯後的PHP檔案路徑。

}

defined('IN_PHPCMS') or exit('Access Denied');

function template_compile($module,$template) //和下面那個一樣是編譯模板啟動函數。不過兩函數的參數不一樣,按照上下文意思。這個函數是為了配合批量編譯模板而寫的。第一個是模組目錄名,第二是模板檔案名稱,解釋同下。請看下面那個

{

global $CONFIG;

$content = file_get_contents(PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html');

$content = template_parse($content);

$compiledtplfile = $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';

$strlen = file_put_contents($compiledtplfile, $content);

@chmod($compiledtplfile, 0777);

return $strlen;

}

function template_refresh($tplfile,$compiledtplfile) //模板編譯啟動函數。 參數 第一個是 模板檔案名稱  第二個是 編譯後的php檔案名稱

{

$str = file_get_contents($tplfile); //使用了php5 的最爽函數:file_get_contents() 擷取檔案的內容 。

$str = template_parse($str); /*然後 使用 template_parse() 函數來對檔案內容進行替換。比如把一些我們自己定義的語句:{if xx > xx}  正則替換成 <?php if(xx > xx){?>具體看下面*/

$strlen = file_put_contents($compiledtplfile, $str);//編譯完成後。把內容寫到我們的 那個所謂的編譯PHP檔案。

@chmod($compiledtplfile, 0777);  //別忘了設定下許可權。

return $strlen; //返回 寫到編譯檔案裡的內容字大小節數,下面我們看下 template_parse() 函數

}

function template_module($module)//這個很有用。批量編譯某模組目錄下的模板檔案

{

global $CONFIG;

$files = glob(PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/*.html');

/*

glob 函數  取得 在此路徑下的所有 *.html 以html為副檔名的檔案清單。 具體看手冊。

**/

if(is_array($files))

{

  foreach($files as $tpl)

  { //開始批量

   $template = str_replace('.html', '', basename($tpl));

   // 擷取模板檔案名稱。以次來做編譯後的PHP檔案名稱

   template_compile($module, $template); //這個函數上面講過了。看上面

  }

}

return TRUE;

}

function template_cache() //這個是比上面那個更大批量的產生。因為 $MODULE 裡面的所有模組  $MODULE 存在於快取檔案模板。前面已經說了。自己看吧

{

    global $MODULE;

foreach($MODULE as $module=>$m)

    {

        template_module($module);

}

return TRUE;

}

/**

哇,別給它嚇到。其實都是些簡單的正則。只要知道他們是幹什麼的就好辦了。 在模板裡面我們使用了些自己定義的標籤呀。語句呀。這些東西不是PHP標準文法。所以根本不可能運行。

那麼怎麼辦呢。通過正則對我們自己定義的文法 。轉變成標準的PHP文法。然後寫到我們的 PHP檔案裡。所以下面正則都是對我們自己定義的文法進行編譯。

下面講解下正則。按照本人水平解釋。大概的解釋了下。不過不懂正則的請自己百度學下。有不對的地方。大家可以討論下。@@   還沒懂 preg_replace() 函數的同學兄弟朋友姐妹。請自己看手冊。

*/

function template_parse($str)

{

$str = preg_replace("/([\n\r]+)\t+/s","\\1",$str); 

// 用 \n\r 過濾掉 tab定位字元,  \\1 是逆向引用了第一個括弧裡面\n換行\r換頁匹配的文本 (@@解釋好要口,最好自己看下正則知識 /s為修正符。自己百度吧)

$str = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}",$str);

// 以 {xx} 來替換 <!--{xx}--> {xx}在下面肯定還要進行第二次正則替換,要不是不能在PHP裡面啟動並執行。  .+? 和 .+ 一個是懶惰 一個是貪婪。  看名字就知道。不知道的 百度吧: 正則貪婪。

$str = preg_replace("/\{template\s+(.+)\}/","\n<?php include template(\\1); ?>\n",$str);

/* 把模板裡面的 {template 'xx','jj'} 編譯成PHP標準寫法:<?php include template('xx','jj') ?>   大家可能一看就明白了: include template()  這個在那裡見過。對了。這個在PHP裡也可以啟動並執行。因為 template() 函數不是定義了嗎。*/

$str = preg_replace("/\{include\s+(.+)\}/","\n<?php include \\1; ?>\n",$str);

/* 模板裡面的 {include xx.php} 編譯成 PHP檔案裡的 <?php include xx.php?>**/

$str = preg_replace("/\{php\s+(.+)\}/","\n<?php \\1?>\n",$str);

/* 模板裡面的 {php xxxx} 編譯成 <?php xxxx?>  大家也應該明白了。 xxxx 肯定是PHP的標準文法拉。 所以phpcms模板語句: {php } 就是用來給你在模板裡寫要啟動並執行PHP語句。在smarty 裡也有這功能**/

$str = preg_replace("/\{if\s+(.+?)\}/","<?php if(\\1) { ?>",$str);

/* 這個就更簡單了。 把模板裡面的{if xxxx}  編譯成 <?php if(){?>  看這樣一步一步的把一些自己定義的語句編譯成PHP的標準文法。這個就叫模板引擎了。**/

$str = preg_replace("/\{else\}/","<?php } else { ?>",$str);

/* {else } 轉 <?php } else {?>**/

$str = preg_replace("/\{elseif\s+(.+?)\}/","<?php } elseif (\\1) { ?>",$str);

/* {elseif } 轉 <?php } elseif {?>**/

$str = preg_replace("/\{\/if\}/","<?php } ?>",$str);

/* {/if} 轉 <?php }?>  phpcms 模板文法有: {/if}的哦。大家別忘了,要不 php肯定運行不了**/

$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/","<?php if(is_array(\\1)) foreach(\\1 AS \\2) { ?>",$str);

/* 下面就是迴圈了。模板裡用{loop xx jj} 其實編譯成了PHP的 foreach(xx AS jj) 這樣大家都會用了吧**/

$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/","\n<?php if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>",$str);

/* 這句和上面也差不多。不過是多了個取出數組的標名  {loop xx jj yy}  成 foreach(xx as jj=> yy)**/

$str = preg_replace("/\{\/loop\}/","\n<?php } ?>\n",$str);

/* 迴圈結束別忘了 {/loop}  對應PHP的 <?php }?>**/

$str = preg_replace("/\{tag_([^}]+)\}/e", "get_tag('\\1')", $str);

/* {tag_xx}  替換為 get_tag('xx')  get_tag()  函數是自己定義的函數,因為phpcms 的模板引擎應用了標籤功能。這個函數就是為了調用標籤的。**/

$str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/","<?php echo \\1;?>",$str);

/* {xxx(jj)}  這麼個奇怪的東西。因為奇怪所以我找了下PHPCMS的模板檔案。找了幾個檔案都沒發現這個怪物。大家有誰找到的說下我去看下。怕是我理解錯了正則。先謝了**/

$str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/","<?php echo \\1;?>",$str);

/* {$xxx(wwsd)} 專換成 <?php echo xxx(wwsd)?>   當然了 xxx() 是程式中定義過的函數**/

$str = preg_replace("/\{([a-zA-Z0-9_\x7f-\xff]*)\}/]\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/","<?php echo \\1;?>",$str);

/* 把{$xxjj} 轉成 <?php echo $xxjj?>  當然了是把變數輸出**/

$str = preg_replace("/\{(\]\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es", "addquote('<?php echo \\1;?>')",$str);

/* 主要是把{$xxx['jj']} 轉成 <?php echo $xxx['jj']?>  addquote() 函數自己定義的看下面,二次過濾。有代驗證,頭昏了看太久的黃色字。我昏**/

$str = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>",$str);

/* {XXJJ}  <?php echo XXJJ?>  XXJJ 是我們定義的常量**/

$str = "<?php defined('IN_PHPCMS') or exit('Access Denied'); ?>".$str;

/* 最後別忘了在自己的每個編譯後的檔案裡加上這個。以前講過了不明白找前面例子**/

return $str; //最後返回過濾完成的內容

}

function get_tag($tagname) //這個函數在  上面這個編譯函數裡面看到了。 其實就是擷取對應標籤的內容,頭有點昏,下節再說標籤吧。

{

global $tags,$html,$CONFIG;

    if(!$tags) require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/tags.php';

    if(!$html) require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/html.php';

if(!isset($tags[$tagname])) return '{tag_'.$tagname.'}';

$code = isset($html[$tagname]) ? 'tag_read('.$html[$tagname].')' : $tags[$tagname];

return "<?php echo $code;?>";

}

function addquote($var)

{

return str_replace("[url=]\\\[/url]"", """, preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));

}

?>

[size=xx-small][/size]

愛J2EE關注Java邁克爾傑克遜視頻站JSON線上工具

http://biancheng.dnbcw.info/php/357338.html pageNo:2

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.