睡蓮‧池水間

Guest
2012-Feb-12  
0 位會員和 7 位訪客在線上

文章 :: 語言集

Smarty 入門

子標題:Smarty 入門 - 4
  1. 重覆的區塊
  2. 巢狀資料的呈現
  3. 轉換資料庫中的資料

控制樣版的內容

重覆的區塊

上面筆者提到,針對單一的一階陣列,我們可以直接將它 assign 到樣版上;但如果我們想將資料庫所選取出來的多筆資料一次顯示到樣版上時,勢必要透過迴圈將資料傾印出來。在樣版裡,我們可以利用重覆的區塊來完成這樣的動作。

在 Smarty 樣板中,我們要重覆一個區塊有兩種方式: foreach 及 section 。而在程式中我們則要 assign 一個陣列,這個陣列中可以包含數組陣列。就像下面這個例子:

首先我們來看 PHP 程式是如何寫的:

test2.php

<?php
require "main.php";
$array1 = array(1 => "蘋果", 2 => "鳳梨", 3 => "香蕉", 4 => "芭樂");
$tpl->assign("array1", $array1);

$array2 = array(
array("index1" => "data1-1", "index2" => "data1-2", "index3" => "data1-3"),
array("index1" => "data2-1", "index2" => "data2-2", "index3" => "data2-3"),
array("index1" => "data3-1", "index2" => "data3-2", "index3" => "data3-3"),
array("index1" => "data4-1", "index2" => "data4-2", "index3" => "data4-3"),
array("index1" => "data5-1", "index2" => "data5-2", "index3" => "data5-3"));
$tpl->assign("array2", $array2);

$tpl->display("test2.htm");
?>

而樣版的寫法如下:

templates/test2.htm

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>測試重覆區塊</title>
</head>
<body>
<pre>

直接呈現 array1
{$array1.1}
{$array1.2}
{$array1.3}
{$array1.4}

利用 foreach 來呈現 array1
{foreach item=item1 from=$array1}
{$item1}
{/foreach}

利用 section 來呈現 array1
{section name=sec1 loop=$array1}
{$array1[sec1]}
{/section}

利用 foreach 來呈現 array2
{foreach item=index2 from=$array2}
{foreach key=key2 item=item2 from=$index2}
{$key2} : {$item2}
{/foreach}
{/foreach}

利用 section 來呈現 array2
{section name=sec2 loop=$array2}
index1: {$array2[sec2].index1}
index2: {$array2[sec2].index2}
index3: {$array2[sec2].index3}
{/section}

</pre>
</body>
</html>

執行上例後,我們發現不管是 foreach 或 section 兩個執行結果是一樣的。那麼兩者到底有何不同呢?

第一個差別很明顯,就是 foreach 要以巢狀處理的方式來呈現我們所 assign 的兩層陣列變數,而 section 則以「主陣列[迴圈名稱].子陣列索引」即可將整個陣列呈現出來。由此可知, Smarty 在樣版中的 foreach 和 PHP 中的 foreach 是一樣的;而 section 則是 Smarty 為了處理如上列的陣列變數所發展出來的敘述。當然 section 的功能還不只如此,除了下一節所談到的巢狀資料呈現外,官方手冊中也提供了好幾個 section 的應用範例。

不過要注意的是,丟給 section 的陣列索引必須是從 0 開始的正整數,即 0, 1, 2, 3, ...。如果您的陣列索引不是從 0 開始的正整數,那麼就得改用 foreach 來呈現您的資料。您可以參考官方討論區中的此篇討論,其中探討了 section 和 foreach 的用法。

巢狀資料的呈現

樣版引擎裡最令人傷腦筋的大概就是巢狀資料的呈現吧,許多著名的樣版引擎都會特意強調這點,不過這對 Smarty 來說卻是小兒科。

最常見到的巢狀資料,就算論譠程式中的討論主題區吧。假設要呈現的結果如下:
公告區
 站務公告
文學專區
 奇文共賞
好書介紹
電腦專區
 軟體討論
硬體週邊

程式中我們先以靜態資料為例:

test3_1.php

<?php
require "main.php";
$forum = array(
    array("category_id" => 1, "category_name" => "公告區",
        "topic" => array(
            array("topic_id" => 1, "topic_name" => "站務公告")
        )
    ),
    array("category_id" => 2, "category_name" => "文學專區",
        "topic" => array(
            array("topic_id" => 2, "topic_name" => "好書介紹"),
            array("topic_id" => 3, "topic_name" => "奇文共賞")
        )
    ),
    array("category_id" => 3, "category_name" => "電腦專區",
        "topic" => array(
            array("topic_id" => 4, "topic_name" => "硬體週邊"),
            array("topic_id" => 5, "topic_name" => "軟體討論")
        )
    )
);
$tpl->assign("forum", $forum);
$tpl->display("test3.htm");
?>

樣版的寫法如下:

templates/test3.htm

<html>
<head>
<title>巢狀迴圈測試</title>
</head>
<body>
<table width="200" border="1" align="center" cellpadding="3" cellspacing="0">
{section name=sec1 loop=$forum}
<tr>
<td colspan="2"> {$forum[sec1].category_name} </td>
</tr>
{section name=sec2 loop=$forum[sec1].topic}
<tr>
<td width="25">&nbsp;</td>
<td width="164"> {$forum[sec1].topic[sec2].topic_name} </td>
</tr>
{/section}
{/section}
</table>
</body>
</html>

執行的結果就像筆者上面舉的例子一樣。

因此呢,在程式中我們只要想辦法把所要重覆值一層一層的塞到陣列中,再利用 {第一層陣列[迴圈1].第二層陣列[迴圈2].第三層陣列[迴圈3]. ... .陣列索引} 這樣的方式來顯示每一個巢狀迴圈中的值。至於用什麼方法呢?下一節使用資料庫時我們再提。

轉換資料庫中的資料

上面提到如何顯示巢狀迴圈,而實際上應用時我們的資料可能是從資料庫中抓取出來的,所以我們就得想辦法把資料庫的資料變成上述的多重陣列的形式。這裡筆者用 MySQLi 來抓取資料庫中的資料,如果各位有其他自己喜好的資料庫抽象套件的話,原理也是差不多的。

我們只修改 PHP 程式,樣版還是上面那個 (這就是樣版引擎的好處~),而且抓出來的資料就是上面的例子。

test3_2.php

<?php
require "main.php";

// 建立資料庫連結
$mysqli = new mysqli("localhost", "username", "password", "testdb");

// 先建立第一層陣列及 SQL 指令
$category = array();
$sql1 = "SELECT category_id, category_name FROM categories";

// 抓取第一層迴圈的資料
if ($result1 = $mysqli->query($sql1)) {

    while ($item_category = $result1->fetch_assoc())
    {
        // 建立第二層陣列及 SQL 指令
        $topic = array();
        $sql2 = sprintf(
            "SELECT topic_id, topic_name FROM topics WHERE category_id = '%s'",
            $item_category['category_id']
        );

        // 抓取第二層迴圈的資料
        if ($result2 = $mysqli->query($sql2)) {
            while ($item_topic = $result2->fetch_assoc())
            {
                // 把抓取的資料推入第二層陣列中
                array_push($topic, $item_topic);
            }
            $result2->close();
        }

        // 把第二層陣列指定為第一層陣列所抓取的資料中的一個成員
        $item_category['topic'] = $topic;

        // 把第一層資料推入第一層陣列中
        array_push($category, $item_category);

        $result1->close();
    }
}
$mysqli->close();

$tpl->assign("forum", $category);
$tpl->display("test3.htm");
?>

在資料庫抓取一筆資料後,我們得到的是一個包含該筆資料的陣列。透過 while 敘述及 array_push 函式,我們將資料庫中的資料一筆一筆塞到陣列裡。如果您只用到單層迴圈,就把第二層迴圈 (紅色的部份) 去掉即可。


    «« HostGator 的 inodes Opera下的text-shadow »»    

引用

  • 文章地址: http://waterlily-lsl.com/modules/article/view.article.php/c2/79
  • 引用地址: http://waterlily-lsl.com/modules/article/trackback.php/79

評分

10
9
8
7
6
5
4
3
2
1


 

API: RSS | RDF | ATOM

回覆及設定

    關閉


 

最 新 發 表 及 資 訊 區

此為池水間 banner ,需要安裝 Adobe Flash Player 才能觀看內容。

最新留言

最新留言:2012-Jan-6 11:13am
留言編號:76
留言者: wuji888
網主回覆:
總留言數: 71

前往萍踪留影

造訪統計

今天:587
昨天:544
本週:587
本月:6427
總計:376811
平均:292

連結

Powered By XOOPS
Valid XHTML 1.1
Valid CSS 3
登 入