Smarty 3 重寫核心架構,API 命名風格改為駝峰式 (camelCase),且移除部分舊方法。SmartyBC (Backward Compatibility) 類別繼承 Smarty,提供 Smarty 2 風格的方法別名,讓舊專案零修改升級至 Smarty 3。
<?php
require_once dirname(__FILE__) . '/Smarty.class.php';
/**
* Smarty 2 相容性包裝類別
*/
class SmartyBC extends Smarty {
public $_version = self::SMARTY_VERSION;
public function __construct(array $options = []) {
parent::__construct($options);
// 註冊 {php}{/php} 標籤 (Smarty 3 預設移除)
$this->registerPlugin('block', 'php', 'smarty_php_tag');
}
// === 指派變數 ===
public function assign_by_ref($tpl_var, &$value) {
$this->assignByRef($tpl_var, $value);
}
public function append_by_ref($tpl_var, &$value, $merge = false) {
$this->appendByRef($tpl_var, $value, $merge);
}
public function clear_assign($tpl_var) {
$this->clearAssign($tpl_var);
}
// === 註冊外掛 (Smarty 2 風格方法名) ===
public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null) {
$this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs);
}
public function unregister_function($function) {
$this->unregisterPlugin('function', $function);
}
public function register_object($object, $object_impl, $allowed = [], $smarty_args = true, $block_methods = []) {
$this->registerObject($object, $object_impl, $allowed, $smarty_args, $block_methods);
}
public function unregister_object($object) {
$this->unregisterObject($object);
}
public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null) {
$this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs);
}
public function unregister_block($block) {
$this->unregisterPlugin('block', $block);
}
public function register_compiler_function($function, $function_impl, $cacheable = true) {
$this->registerPlugin('compiler', $function, $function_impl, $cacheable);
}
public function unregister_compiler_function($function) {
$this->unregisterPlugin('compiler', $function);
}
public function register_modifier($modifier, $modifier_impl) {
$this->registerPlugin('modifier', $modifier, $modifier_impl);
}
public function unregister_modifier($modifier) {
$this->unregisterPlugin('modifier', $modifier);
}
// === 資源管理 ===
public function register_resource($type, $functions) {
$this->registerResource($type, $functions);
}
public function unregister_resource($type) {
$this->unregisterResource($type);
}
// === 過濾器 ===
public function register_prefilter($function) {
$this->registerFilter('pre', $function);
}
public function unregister_prefilter($function) {
$this->unregisterFilter('pre', $function);
}
public function register_postfilter($function) {
$this->registerFilter('post', $function);
}
public function unregister_postfilter($function) {
$this->unregisterFilter('post', $function);
}
public function register_outputfilter($function) {
$this->registerFilter('output', $function);
}
public function unregister_outputfilter($function) {
$this->unregisterFilter('output', $function);
}
public function load_filter($type, $name) {
$this->loadFilter($type, $name);
}
// === 快取管理 ===
public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) {
return $this->clearCache($tpl_file, $cache_id, $compile_id, $exp_time);
}
public function clear_all_cache($exp_time = null) {
return $this->clearCache(null, null, null, $exp_time);
}
public function is_cached($tpl_file, $cache_id = null, $compile_id = null) {
return $this->isCached($tpl_file, $cache_id, $compile_id);
}
// === 變數管理 ===
public function clear_all_assign() {
$this->clearAllAssign();
}
public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) {
return $this->clearCompiledTemplate($tpl_file, $compile_id, $exp_time);
}
// === 工具方法 ===
public function template_exists($tpl_file) {
return $this->templateExists($tpl_file);
}
public function get_template_vars($name = null) {
return $this->getTemplateVars($name);
}
public function get_config_vars($name = null) {
return $this->getConfigVars($name);
}
public function config_load($file, $section = null, $scope = 'global') {
$this->ConfigLoad($file, $section, $scope);
}
public function get_registered_object($name) {
return $this->getRegisteredObject($name);
}
public function clear_config($var = null) {
$this->clearConfig($var);
}
public function trigger_error($error_msg, $error_type = E_USER_WARNING) {
trigger_error("Smarty error: $error_msg", $error_type);
}
}
/**
* {php}{/php} 區塊外掛實作
* 允許模板中直接執行 PHP 程式碼 (極度不建議,安全風險高)
*/
function smarty_php_tag($params, $content, $template, &$repeat) {
eval($content);
return '';
}
| Smarty 2 (舊) | Smarty 3 (新) | SmartyBC 別名 | 說明 |
|---|---|---|---|
| assign_by_ref | assignByRef | ✓ assign_by_ref | 參考指派變數 |
| append_by_ref | appendByRef | ✓ append_by_ref | 參考追加陣列元素 |
| clear_assign | clearAssign | ✓ clear_assign | 清除指派變數 |
| register_function | registerPlugin('function',...) | ✓ register_function | 註冊自訂函式標籤 |
| register_object | registerObject | ✓ register_object | 註冊物件供模板存取 |
| register_block | registerPlugin('block',...) | ✓ register_block | 註冊區塊標籤 |
| register_modifier | registerPlugin('modifier',...) | ✓ register_modifier | 註冊修飾器 |
| register_resource | registerResource | ✓ register_resource | 註冊模板資源來源 |
| register_prefilter | registerFilter('pre',...) | ✓ register_prefilter | 編譯前過濾 |
| register_postfilter | registerFilter('post',...) | ✓ register_postfilter | 編譯後過濾 |
| register_outputfilter | registerFilter('output',...) | ✓ register_outputfilter | 輸出過濾 |
| load_filter | loadFilter | ✓ load_filter | 載入過濾器 |
| clear_cache | clearCache | ✓ clear_cache | 清除快取 |
| clear_all_cache | clearCache(null...) | ✓ clear_all_cache | 清除所有快取 |
| is_cached | isCached | ✓ is_cached | 檢查快取是否存在 |
| template_exists | templateExists | ✓ template_exists | 檢查模板是否存在 |
| get_template_vars | getTemplateVars | ✓ get_template_vars | 取得指派變數 |
| config_load | ConfigLoad | ✓ config_load | 載入設定檔 |
| trigger_error | trigger_error | ✓ trigger_error | 觸發錯誤 |
// 舊 require 'Smarty.class.php'; $smarty = new Smarty(); // 新:零程式碼修改 require 'SmartyBC.class.php'; $smarty = new SmartyBC();
require 'Smarty.class.php';
$smarty = new Smarty();
// 新風格指派
$smarty->assign('name', 'John');
$smarty->assign(['title' => 'Manager', 'dept' => 'IT']);
// 新風格註冊外掛
$smarty->registerPlugin('function', 'my_func', 'myFuncImpl');
$smarty->registerPlugin('modifier', 'upper', 'strtoupper');
// 新風格快取
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);
$smarty->setCacheLifetime(3600);
SmartyBC 為相容而註冊 smarty_php_tag,但 模板中執行 PHP 是嚴重安全漏洞。遷移步驟:
{php}...{/php}。assign() 傳遞資料。SmartyBC,改用 Smarty,不註冊 php tag。| 問題 | 原因 | 解決 |
|---|---|---|
| 模板變數不顯示 | Smarty 3 預設 error_unassigned = false,未指派變數輸出空字串而非報錯 | 設定 $smarty->error_unassigned = true 開發環境啟用 |
| 模板繼承 {block} 不生效 | Smarty 3 區塊語法與 Smarty 2 不同 | 改用 {block name='x'}...{/block} 與 {extends file='layout.tpl'} |
| 修飾器管道符號優先序變化 | Smarty 3 嚴格遵循左至右 | 加上括號明確分組:{$var|modifier1|modifier2} → {($var|modifier1)|modifier2} |
| 編譯後模板路徑不同 | Smarty 3 使用 compile_id、子目錄 | 清除 templates_c/ 重新編譯 |
若專案允許重構,建議遷移至現代模板引擎:
SmartyBC 讓舊專案能平滑過渡至 Smarty 3,但長遠規劃應逐步移除舊式 API 依賴,並評估遷移至現代模板引擎以獲得更好的開發體驗與安全性。