在效能與易用性間取得平衡:採用 HTML 編譯為 PHP 的方式,分離顯示邏輯與商業邏輯,支援美工使用 Dreamweaver 等視覺化工具編輯模板。
<?php
require('./template.php');
$tpl_prefix = 'default'; // 風格前綴
$tpl_index = 'index'; // 模板名稱
$tpl = new Template($tpl_prefix);
// 模擬資料
$cats = array(
array('forum_id'=>'1', 'forum_cat_id'=>'0', 'forum_name'=>'PHP學習'),
array('forum_id'=>'2', 'forum_cat_id'=>'0', 'forum_name'=>'MYSQL學習')
);
$forums = array(
array('forum_id'=>'3', 'forum_cat_id'=>'1', 'forum_name'=>'PHP高級教程'),
array('forum_id'=>'4', 'forum_cat_id'=>'1', 'forum_name'=>'PHP初級教程'),
array('forum_id'=>'5', 'forum_cat_id'=>'2', 'forum_name'=>'MYSQL相關資料')
);
if ($cats) {
if ($tpl->chk_cache($tpl_index)) { // 檢查是否需重新編譯
$tpl->load_tpl($tpl_index); // 載入 HTML 模板
// 替換區塊標籤為 PHP 迴圈
$tpl->assign_block("{block_cat}", "<?foreach(\$cats as \$cat) {?>");
$tpl->assign_block("{/block_cat}", "<?}?>");
$tpl->assign_block("{block_forum}", "<?foreach(\$forums as \$forum) {\nif(\$forum['forum_cat_id'] == \$cat['forum_id']) {?>");
$tpl->assign_block("{/block_forum}", "<?}\n}?>");
$tpl->write_cache($tpl_index); // 生成編譯後 PHP 檔
}
}
include($tpl->parse_tpl($tpl_index)); // 包含編譯後檔案
?>
{block_cat}
<table width="100%" border="0" cellspacing="1" cellpadding="1" bgcolor="#000000" align="center">
<tr align="{=TR_ALING}" bgcolor="#FFFFFF">
<td colspan="6"><span class="title"><b>{=$cat['forum_name']}</b></span></td>
</tr>
{block_forum}
<tr bgcolor="#FFFFFF">
<td valign="top">{=$forum['forum_name']}</td>
</tr>
{/block_forum}
</table>
<br>
{/block_cat}
<?foreach($cats as $cat) {?>
<table width="100%" border="0" cellspacing="1" cellpadding="1" bgcolor="#000000" align="center">
<tr align="<?=TR_ALING?>" bgcolor="#FFFFFF">
<td colspan="6"><span class="title"><b><?=$cat['forum_name']?></b></span></td>
</tr>
<?foreach($forums as $forum) {
if($forum['forum_cat_id'] == $cat['forum_id']) {?>
<tr bgcolor="#FFFFFF">
<td valign="top"><?=$forum['forum_name']?></td>
</tr>
<?
}
}?>
</table>
<br>
<?}?>
class Template {
var $template = '';
var $tpl_path = '';
var $tpl_prefix = '';
var $cache_path = '';
var $css_path = '';
var $header_path = '';
var $footer_path = '';
function Template($root = 'default') {
$this->tpl_prefix = $root;
$this->tpl_path = './templates/' . $root . '/';
$this->cache_path = './template_data/' . $this->tpl_prefix . '_';
return true;
}
// 檢查快取是否過期
function chk_cache($tpl_index) {
$tpl_file = $this->tpl_path . $tpl_index . '.html';
$cache_file = $this->cache_path . $tpl_index . '.php';
if (!file_exists($cache_file)) return true;
elseif (filemtime($tpl_file) > filemtime($cache_file)) return true;
return false;
}
function parse_tpl($tpl_index, $message = '') {
return $this->cache_path . $tpl_index . '.php';
}
function load_tpl($tpl_index) {
$tpl_file = $this->tpl_path . $tpl_index . '.html';
$fp = fopen($tpl_file, 'r');
$this->template = fread($fp, filesize($tpl_file));
fclose($fp);
}
function write_cache($tpl_index) {
$cache_file = $this->cache_path . $tpl_index . '.php';
// 變數顯示標籤 {=var} => =var?>
$this->template = preg_replace("/(\{=)(.+?)(\})/is", "<?=\\2?>", $this->template);
// 語言包標籤 {lang key} => $lang['main']['key']
$this->template = preg_replace("/\{lang +(.+?)\}/ies", "\$lang['main']['\\1']", $this->template);
$fp = fopen($cache_file, 'w');
flock($fp, 3);
fwrite($fp, $this->template);
fclose($fp);
}
function assign_block($search, $replace) {
$this->template = str_replace($search, $replace, $this->template);
}
}
{=var}、區塊迴圈 {block}/{/block}、語言包 {lang key}