Smarty 3.1 對比 2.x 重寫核心、支援 PHP 5.3+、模板繼承、沙箱模式、效能提升。本文將註冊模組遷移至 Smarty 3.1.18,目錄結構更清晰。
ROOT/
├─ libs/ # Smarty 核心(從壓縮包複製)
├─ templates/ # 模板檔
├─ templates_c/ # 編譯快取
├─ plugins/ # 自訂插件
├─ cache/ # 模板快取
├─ configs/ # 配置檔
├─ init.inc.php # Smarty 初始化
└─ register.php # 業務入口
<?php
// init.inc.php
define("ROOT", str_replace("\\", "/", dirname(__FILE__)) . "/");
require ROOT . 'libs/Smarty.class.php';
$smarty = new Smarty();
$smarty->setTemplateDir(ROOT . 'templates/')
->setCompileDir(ROOT . 'templates_c/')
->setPluginsDir(ROOT . 'plugins/')
->setCacheDir(ROOT . 'cache/')
->setConfigDir(ROOT . 'configs');
$smarty->caching = false;
$smarty->cache_lifetime = 86400; // 1 天
$smarty->left_delimiter = '<{';
$smarty->right_delimiter = '}>';
// 根 URL 常數
$phpSelf = $_SERVER['PHP_SELF'];
$rootUrl = 'https://' . $_SERVER['HTTP_HOST'] . substr($phpSelf, 0, strrpos($phpSelf, '/') + 1);
define('ROOT_URL', $rootUrl);
define('TEMPLATE_DIR', $rootUrl . 'templates');
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>註冊頁面</title>
<link href="<{$TEMPLATE_DIR}>/css/common.css" rel="stylesheet">
<link href="<{$TEMPLATE_DIR}>/css/register.css" rel="stylesheet">
<script src="<{$TEMPLATE_DIR}>/js/jquery-1.8.3.min.js"></script>
<script src="<{$TEMPLATE_DIR}>/js/register.js"></script>
<script src="<{$TEMPLATE_DIR}>/js/emailup.js"></script>
</head>
<body>
<{include file="header.html"}>
<div id="container">
<div id="register">
<form id="register-form" action="register_chk.php" method="post">
<div class="ipt fipt">
<input type="text" name="uname" id="uname" placeholder="輸入用戶名" autocomplete="off">
<span id="unamechk"></span>
</div>
<div class="ipt">
<input type="text" name="uemail" id="uemail" placeholder="常用郵箱地址" autocomplete="off">
<span id="uemailchk"></span>
<ul class="autoul"></ul>
</div>
<div class="ipt">
<input type="password" name="upwd" id="upwd" placeholder="設置密碼">
<div class="upwdpic"><span id="upwdchk"></span><img id="pictie" /></div>
</div>
<div class="ipt">
<input type="password" name="rupwd" id="rupwd" placeholder="確認密碼">
<span id="rupwdchk"></span>
</div>
<div class="ipt iptend">
<input type="text" id="yzm" name="yzm" placeholder="驗證碼" autocomplete="off">
<img id="yzmpic" src="valcode.php?num=<{$showval}>" style="cursor:pointer">
<a id="changea"><img id="refpic" src="<{$TEMPLATE_DIR}>/images/ref.jpg"></a>
<span id="yzmchk"></span>
</div>
<button type="button" id="sub">立即註冊</button>
<span class="fuwu">
<input type="checkbox" name="agree" id="agree" checked>
<label for="agree">我同意 <a href="#">服務條款</a> 和 <a href="#">隱私政策</a></label>
</span>
</form>
</div>
</div>
</body>
</html>
<?php
session_start();
require_once 'init.inc.php';
$smarty->assign("TEMPLATE_DIR", TEMPLATE_DIR);
$smarty->display('register.html');
檔案:plugins/function.showval.php
<?php
function smarty_function_showval($params, $smarty) {
$num = '';
for ($i = 0; $i < 4; $i++) {
$tmp = rand(1, 15);
$num .= ($tmp > 9) ? chr(ord('a') + $tmp - 10) : $tmp;
}
$mdnum = md5($num);
$_SESSION['num'] = $num;
$_SESSION['mdnum'] = $mdnum;
return $mdnum; // 模板中輸出加密值作為圖片參數
}
// 確保 Session 已啟動
if (session_status() === PHP_SESSION_NONE) session_start();
$_SESSION['num'] = smarty_function_showval(null, $smarty);
$_SESSION['mdnum'] = md5($_SESSION['num']);
插件命名規範:function.插件名.php、函數名smarty_function_插件名($params, $smarty)、需有回傳值。
<{ ... }> 避免與 JS 模板衝突{block})升級 Smarty 3.1 並重構目錄結構,讓註冊模組更具可維護性與擴展性。插件機制將業務邏輯(驗證碼生成)從模板中剝離,符合關注點分離原則。