| 標籤 | 類型 | 編譯目標 | 適用場景 |
|---|---|---|---|
<if condition="..."> | 條件判斷 | PHP if (...) | 複雜邏輯、多條件、函數呼叫 |
<eq name="..." value="..."> | 比較標籤 | PHP if ($name == $value) | 單一變數等值比較 |
<neq name="..." value="..."> | 比較標籤 | PHP if ($name != $value) | 單一變數不等比較 |
<if condition="$item.group_id eq $one.group_id">...</if> <eq name="item.group_id" value="$one.group_id">...</eq>
原因:condition 內部使用 ThinkPHP 模板引擎解析,eq 關鍵字在條件表達式中優先級/解析邏輯有缺陷。eq/neq 標籤專門處理變數比較,編譯器直接生成 ==/!=。
<if condition="name neq 'NULL'">...</if> <neq name="name" value="">...</neq>
關鍵差異:value="" 在編譯時會轉為 ''(空字串),而 condition 中的 'NULL' 是字面字串 "NULL",非 PHP null。
<if condition="name.0 neq 'test'">...</if> <eq name="name.0" value="test">...</eq>
| 規則 | if 標籤 | eq/neq 標籤 |
|---|---|---|
| 變數前綴 | 需 $ | name 不需 $,value 需 $ |
| 字串引號 | 單雙引號均可 | value 內字串需引號 |
| 陣列下標 | 點號 name.0 | 點號 name.0 |
| 多條件 | 支援 and/or | 不支援,需巢狀 |
| 函數呼叫 | 支援 | 不支援 |
graph TD
A[需要比較] --> B{比較類型}
B -->|單一變數 ==/!= 值| C[使用 eq/neq]
B -->|多條件/函數/複雜邏輯| D[使用 if condition]
B -->|變數之間比較| D
B -->|NULL/空值判斷| C
B -->|陣列下標為數字| C
<eq name="status" value="1">啟用</eq>
<neq name="status" value="1">停用</neq>
<eq name="user.role" value="$adminRole">管理員</eq>
<if condition="$user.score > 60 and $user.status eq 1">
及格且啟用
<elseif condition="$user.score > 60" />
僅及格
<else />
不及格
</if>
<neq name="title" value="">{$title}</neq>
<eq name="description" value="">無描述</eq>
// ThinkPHP 3.2+ 擴展標籤
// 增加 gt/lt/egt/elt 等比較標籤
namespace Think\Template\TagLib;
class Cx extends TagLib {
protected $tags = [
'gt' => ['attr' => 'name,value', 'close' => 1],
'lt' => ['attr' => 'name,value', 'close' => 1],
'between' => ['attr' => 'name,min,max', 'close' => 1],
];
public function _gt($tag, $content) {
$name = $tag['name'];
$value = $tag['value'];
return " {$value}): ?>{$content}";
}
// ... lt, between 類似
}
簡單比較用 eq/neq,複雜邏輯用 if。這不是偏好問題,是 ThinkPHP 模板編譯器的實現機制決定的。eq/neq 專門優化了「變數與值比較」的解析路徑,避開了 condition 表達式解析器的已知缺陷(變數間比較、NULL 處理、數字下標)。遵循此原則,可消除 90% 的模板比較 Bug。