Smarty 作為經典 PHP 模板引擎,其 {if}、{else}、{/if} 語法是模板邏輯控制的核心。本文從模板寫法、編譯器解析實現、緩存文件生成三個維度全面解析。
{* 基礎 if *}
{if $condition}
條件成立顯示內容
{/if}
{* if-else *}
{if $condition}
條件成立
{else}
條件不成立
{/if}
{* 多條件判斷 *}
{if $a > $b}
a 大於 b
{elseif $a == $b}
a 等於 b
{else}
a 小於 b
{/if}
{* 支援運算符 *}
> < == === >= <= != !==
and or not xor
% (取模) is [not] div by (整除判斷)
is [not] even/odd (奇偶判斷)
<?php
// 1. 匹配 {if 條件}
$if_operators = array(">", "<", "==", "===", ">=", "<=", "!=", "!==");
$pattern_if = "/\{if\s+((.*?))\}/";
preg_match_all($pattern_if, $content, $match_if);
if (isset($match_if[1]) && is_array($match_if[1])) {
foreach ($match_if[1] as $key_if => $val_if) {
$is_operator = false;
// 2. 識別運算符並拆分左右操作數
foreach ($if_operators as $if_operator) {
$items = explode($if_operator, $val_if);
if (count($items) == 2) {
$is_operator = true;
// 3. 判斷是變量還是常量($ 開頭為變量)
$shift_left = substr($items[0], 0, 1);
$pop_left = substr($items[0], 1);
$shift_right = substr($items[1], 0, 1);
$pop_right = substr($items[1], 1);
$left_var = ($shift_left == '$')
? '$this->var_tpl_arr["' . $pop_left . '"]'
: $items[0];
$right_var = ($shift_right == '$')
? '$this->var_tpl_arr["' . $pop_right . '"]'
: $items[1];
// 4. 替換為 PHP 原生 if
$content = str_replace(
$match_if[0][$key_if],
"",
$content
);
break;
}
}
// 5. 無運算符時視為布爾判斷
if (!$is_operator) {
$content = str_replace(
$match_if[0][$key_if],
"",
$content
);
}
}
}
// 6. 處理 {/if} {else} {/else}
$patterns = array(
"/\{\/if\}/" => "",
"/\{else\}/" => "",
"/\{\/else\}/" => "" // Smarty 不需要 {/else} 閉合標籤
);
foreach ($patterns as $pattern => $replace) {
if (preg_match($pattern, $content)) {
$content = preg_replace($pattern, $replace, $content);
}
}
?>
<br/><br/>
$var_left == {$var_left}, $var_right == {$var_right}<br/><br/>
test if >: $var_left > 1
<br/>
{if ($var_left > 1)}
<b>if > 條件成立!</b>
{/if}
<br/>
test if <: $var_left < 5
<br/>
{if ($var_left < 5)}
<b>if < 條件成立!</b>
{/if}
<br/>
test if ==: $var_left == $var_right
<br/>
{if ($var_left == $var_right)}
<b>if == 條件成立!</b>
{else}
<b><font color=red>if == 條件不成立!</font></b>
{/if}
<br/><br/>
$var_left == <?php echo $this->var_tpl_arr["var_left"]; ?>,
$var_right == <?php echo $this->var_tpl_arr["var_right"]; ?>
<br/><br/>
test if >: $var_left > 1
<br/>
<?php if($this->var_tpl_arr["var_left"] > 1) { ?>
<b>if > 條件成立!</b>
<?php } ?>
<br/>
test if <: $var_left < 5
<br/>
<?php if($this->var_tpl_arr["var_left"] < 5) { ?>
<b>if < 條件成立!</b>
<?php } ?>
<br/>
test if ==: $var_left == $var_right
<br/>
<?php if($this->var_tpl_arr["var_left"] == $this->var_tpl_arr["var_right"]) { ?>
<b>if == 條件成立!</b>
<?php } else { ?>
<b><font color=red>if == 條件不成立!</font></b>
<?php } ?>
{if ...}、{else}、{/if}$this->var_tpl_arr[key]if/else 控制結構{$var_left} 與 {$va_right} 這類拼寫錯誤{if $var} 簡潔判斷非空/真值,而非 {if $var == true}$smarty->caching = false),生產環境開啟並設置合理生命週期理解 Smarty 編譯原理,不僅能編寫更高效模板,也能在調試緩存異常、自定義插件時得心應手。