在 ThinkPHP 模板引擎中,volist 標籤是輸出列表數據的核心標籤。不同於 Smarty 的 $smarty.foreach.name.last,ThinkPHP 通過內置變量 $i(默認鍵名)配合 count() 實現「是否最後一條」判斷。本文詳細說明語法、進階用法及常見坑點。
| 屬性 | 說明 | 默認值 |
|---|---|---|
| name | 模板變量名(必填) | - |
| id | 循環變量名(必填) | - |
| offset | 起始偏移量 | 0 |
| length | 輸出長度 | 全部 |
| key | 鍵名變量 | i |
| mod | 取模數(用於斑馬紋) | 2 |
| empty | 空數據顯示文本 | - |
<volist name="lists" id="list">
<li <if condition="$i eq count($lists)">class="last"</if>>
<a href="/tag/thinkphp">{{$list.title}}</a>
</li>
</volist>
$i 是內置計數器:從 1 開始遞增,對應當前循環第幾項。可通過 key="k" 自定義變量名(則使用 $k)。count($lists) 直接在模板中調用 PHP 函數:ThinkPHP 模板解析階段允許在 condition 中使用 PHP 語法,$lists 為傳入的數組變量。$i == 總數 時,即為最後一條,輸出 class="last"。若使用了 offset 或 length,count($lists) 仍返回原數組總長度,導致判斷失效。正確做法:
<!-- 控制器預處理 -->
<?php
// 只切片需要顯示的數據
$displayList = array_slice($lists, $offset, $length);
$this->assign('displayList', $displayList);
?>
<!-- 模板 -->
<volist name="displayList" id="list">
<li <if condition="$i eq count($displayList)">class="last"</if>>...</li>
</volist>
或在模板中計算實際長度(不推薦,邏輯前置更清晰):
<volist name="lists" id="list" offset="5" length="10">
<!-- 實際輸出長度 = min(length, count(lists)-offset) -->
<php>$actualLen = min(10, count($lists)-5);</php>
<li <if condition="$i eq $actualLen">class="last"</if>>...</li>
</volist>
內層循環會覆蓋外層的 $i。解決方案:使用 key 屬性指定不同變量名。
<volist name="categories" id="cat" key="outerKey">
<h3>{{$cat.name}}</h3>
<ul>
<volist name="cat.items" id="item" key="innerKey">
<li>{{$item.name}}
<if condition="$innerKey eq count($cat.items)">(最後)</if>
</li>
</volist>
</ul>
</volist>
| 誤區代碼 | 問題 | 修正 |
|---|---|---|
<if condition="$vo.last"> | ThinkPHP 無 last 屬性 | 用 $i eq count($list) |
<if condition="$i == count($list)"> | 模板條件需用 eq 而非 == | condition="$i eq count($list)" |
巢狀循環直接用 $i | 內層覆蓋外層計數器 | 指定 key="k1"/key="k2" |
配合 offset/length 直接判斷 | 計數器基於切片後實際輸出,非原數組總長 | 控制器預切片或模板計算實際長度 |
新版本推薦使用原生 PHP 語法,更靈活、IDE 支持更好:
<?php foreach ($lists as $index => $list): ?>
<li class="<?= $index === array_key_last($lists) ? 'last' : '' ?>">
<a href="/tag/thinkphp"><?= htmlspecialchars($list['title']) ?></a>
</li>
<?php endforeach; ?>
array_key_last() (PHP 7.3+) 直接獲取最後一個鍵,語義清晰。「模板引擎解決的是『邏輯與視圖分離』,不是『禁止在視圖寫邏輯』。」—— 合理使用原生 PHP 模板,往往比死記標籤語法更高效。