首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

ThinkPHP volist 標籤進階:多層嵌套循環實戰與關鍵技巧

     編輯:PHP 相關知識

場景背景

在電商或 CMS 系統中,常需展示「分類 → 商品列表」或「問題分類 → 問題列表」這類兩層甚至多層巢狀結構。ThinkPHP 的 <volist> 標籤原生支援多層嵌套,但需注意 key 屬性與變量作用域,否則易出現「內層循環變量覆蓋外層」或「無法判斷最後一項」等問題。

控制器:構建多維陣列

<?php
namespace Home\Controller;
use Think\Controller;

class ServiceController extends Controller
{
    public function index()
    {
        $prod = I('get.prod_en');
        $id   = I('get.id', 0, 'int');

        if (empty($prod)) {
            // 多重循環所需的二維陣列
            $serviceProduct = [];

            $service = M('product_class')->order('oid ASC')->select();
            foreach ($service as $item) {
                $products = M('product')
                    ->where(['prod_class_id' => $item['pcid']])
                    ->order('oid ASC')
                    ->select();
                $serviceProduct[] = [
                    'srvName' => $item['pc_cn'],
                    'product' => $products,
                ];
            }

            $this->assign('serviceProduct', $serviceProduct);
            $this->display();
        } else {
            // 其他分支略...
        }
    }
}

模板:正確的嵌套寫法

<volist name="serviceProduct" id="sp" key="i">
    <dl class="dlist <?php echo ($i % 2) ? 'odd' : 'even'; ?>">
        <dt>{$sp.srvName}</dt>

        <volist name="sp.product" id="pd" key="j">
            <dd>{$pd.prod_cn}</dd>
            <!-- 判斷是否為最後一項,避免多餘分隔符 -->
            <if condition="$j lt count($sp['product'])">
                <dd>|</dd>
            </if>
        </volist>

        <!-- 空分類顯示佔位 -->
        <if condition="count($sp['product']) eq 0">
            <dd>暫無產品</dd>
        </if>
    </dl>
</volist>

關鍵技巧解析

技巧說明
指定 key 屬性 每一層 volist 必須設定唯一 key(如 i、j),否則內層循環會覆蓋外層的 $key 變量,導致條件判斷失效。
引用外層陣列長度 內層判斷最後一項時,使用 count($sp['product']) 而非 count($pd);$sp 為外層當前項對象,可直接存取其 product 子陣列。
空陣列防禦 若某分類無商品,volist 不會執行,需額外 <if condition="count($sp['product']) eq 0"> 給予友好提示。
CSS 斑馬紋 利用外層 key="i" 判斷奇偶($i % 2),為 dl 動態加 class,實現隔行換色。

進階:三層以上嵌套

若需「大分類 → 小分類 → 商品」,只需再套一層 volist,並依序命名 key="i"、key="j"、key="k"。原理相同,注意變量作用域即可:

<volist name="bigCats" id="big" key="i">
    <volist name="big.smallCats" id="small" key="j">
        <volist name="small.products" id="prod" key="k">
            <!-- 使用 $i, $j, $k 分別控制三層邏輯 -->
        </volist>
    </volist>
</volist>

常見錯誤與修正

  • 錯誤:內層未設 key → 外層 $key 被覆蓋,導致 $key lt count(...) 判斷錯誤。
    修正:每層必設 key 且名稱唯一。
  • 錯誤:condition="$j lt count($pd)" → $pd 是當前項對象而非陣列。
    修正:用 count($sp['product']) 取得外層當前分類的商品總數。
  • 錯誤:控制器未檢查 $products 是否為空陣列。
    修正:select() 回傳空陣列而非 false,模板端 count() 即可安全判斷。

總結

掌握 key 隔離、外層變量引用、空陣列處理三大要點,即可輕鬆駕馭 ThinkPHP 多層 volist 嵌套,構建清晰、可維護的列表頁面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved