Smarty 模板引擎變量使用全攻略:從標量到對象方法調用
Smarty 是 PHP 經典模板引擎,變量系統支援標量、陣列、對象、運算表達式等豐富類型。本文系統講解變量賦值、模板訪問、運算邏輯、對象交互等核心用法,含實戰最佳實踐。
環境初始化
setTemplateDir(__DIR__ . '/templates/');
$smarty->setCompileDir(__DIR__ . '/templates_c/');
$smarty->setConfigDir(__DIR__ . '/configs/');
$smarty->leftDelimiter = '<{';
$smarty->rightDelimiter = '}>';
// 關鍵:解決 __autoload 衝突
spl_autoload_register(function($class) {
$file = __DIR__ . '/lib/' . $class . '.class.php';
if (file_exists($file)) require_once $file;
});
變量賦值與訪問對照表
| PHP 賦值 | 模板語法 | 說明 |
| $smarty->assign('name', '張三') | <{$name}> | 字符串標量 |
| $smarty->assign('age', 25) | <{$age}> | 整數標量 |
| $smarty->assign('price', 99.9) | <{$price}> | 浮點數標量 |
| $smarty->assign('ok', true) | <{$ok}> | 布爾值 (輸出 1/空) |
| $smarty->assign('arr', ['a','b','c']) | <{$arr[0]}> <{$arr[1]}> <{$arr[2]}> | 索引數組 |
| $smarty->assign('arr2', [['a','b'],['c','d']]) | <{$arr2[0][0]}> <{$arr2[1][1]}> | 二維索引數組 |
| $smarty->assign('assoc', ['k1'=>'v1','k2'=>'v2']) | <{$assoc.k1}> <{$assoc.k2}> | 關聯數組 (點語法) |
| $smarty->assign('mix', ['k'=>['a','b'], 'c','d']) | <{$mix.k.0}> <{$mix.0}> | 混合數組 |
| $smarty->assign('obj', new User('李四',30)) | <{$obj->name}> <{$obj->age}> <{$obj->getInfo()}> | 對象屬性/方法 |
模板中變量運算
assign('num1', 10);
$smarty->assign('num2', 20);
$smarty->assign('str1', 'Hello');
$smarty->assign('str2', 'World');
算術運算: <{$num1 + $num2}> <{$num1 - $num2}> <{$num1 * $num2}> <{$num1 / $num2}> <{$num1 % $num2}>
複雜表達式: <{$num1 + $num2 * $num2 / $num1 + 44}>
字符串拼接: <{$str1|cat:' '|cat:$str2}> {* 需 cat 修飾符 *}
邏輯判斷: <{if $num1 > $num2}>大<{else}>小<{/if}>
三元運算: <{$num1 > $num2 ? '大' : '小'}> {* Smarty 3 支援 *}
對象深度交互
name = $name;
$this->age = $age;
$this->email = $email;
}
public function getEmail() { return $this->email; }
public function isAdult() { return $this->age >= 18; }
public function getInfo() { return "{$this->name}, {$this->age}歲"; }
}
$user = new User('王五', 25, 'wang@example.com');
$smarty->assign('user', $user);
姓名: <{$user->name}>
年齡: <{$user->age}>
郵箱: <{$user->getEmail()}>
成年: <{$user->isAdult() ? '是' : '否'}>
信息: <{$user->getInfo()}>
{* 遍歷對象屬性 (需實現 Iterator) *}
<{foreach $user as $key=>$val}>
<{$key}>: <{$val}>
<{/foreach}>
配置文件變量
site_name = "我的網站"
site_url = "https://example.com"
[production]
debug = false
cache_time = 3600
[development]
debug = true
cache_time = 0
<{config_load file="site.conf" section="production"}>
站點: <{#site_name#}>
網址: <{#site_url#}>
調試: <{#debug#}>
緩存: <{#cache_time#}> 秒
保留變量 (系統內置)
| 變量 | 含義 | 示例 |
| $smarty.now | 當前時間戳 | <{$smarty.now|date_format:'%Y-%m-%d'}> → 2024-01-15 |
| $smarty.request.* | $_REQUEST 變量 | <{$smarty.request.id}> <{$smarty.request.keyword}> |
| $smarty.get.* | $_GET 變量 | <{$smarty.get.page}> |
| $smarty.post.* | $_POST 變量 | <{$smarty.post.username}> |
| $smarty.session.* | $_SESSION 變量 | <{$smarty.session.user.name}> |
| $smarty.cookies.* | $_COOKIE 變量 | <{$smarty.cookies.remember_me}> |
| $smarty.server.* | $_SERVER 變量 | <{$smarty.server.REQUEST_URI}> |
| $smarty.env.* | $_ENV 變量 | <{$smarty.env.APP_ENV}> |
| $smarty.const.* | 常量 | <{$smarty.const.PHP_VERSION}> |
| $smarty.version | Smarty 版本 | <{$smarty.version}> → 3.1.39 |
| $smarty.template | 當前模板文件名 | <{$smarty.template}> → index.tpl |
最佳實踐建議
- 變量命名:使用 snake_case,模板中直接使用
<{$user_name}>
- 數據預處理:控制器中完成格式化、截斷、轉義,模板只負責顯示
- 避免複雜邏輯:模板中不放業務邏輯,複雜判斷用 PHP 預計算好布爾變量
- 安全輸出:默認啟用
$smarty->escapeHtml = true,或使用 <{$var|escape}>
- 緩存策略:靜態頁面
$smarty->caching = true; $smarty->cacheLifetime = 3600
- 模板繼承:使用
{block}/{extends} 替代 include,結構更清晰
常見問題排查
| 現象 | 原因 | 解決 |
| 變量不顯示/空白 | 賦值名稱不匹配/大小寫 | 檢查 assign 參數、模板變量名、區分大小寫 |
| 對象方法不執行 | 方法非 public/參數錯誤 | 確保 public、無參或模板傳參正確 |
| 數組下標報錯 | 關聯數組用數字下標 | 關聯數組用點語法 <{$arr.key}> |
| 修飾符不生效 | 修飾符名稱/參數錯誤 | 查閱手冊:<{$var|modifier:param}> |
| 配置文件不加載 | 路徑/section 名錯誤 | 檢查 setConfigDir、文件名、section 大小寫 |
掌握 Smarty 變量系統,能讓模板層保持極簡,業務邏輯集中在 PHP 層,實現真正的關注點分離。