# 快速入門(mén)(九):循環(huán)和控制輸出
在上一章我們了解了如何把變量輸出到模板中,這一篇我們來(lái)進(jìn)一步了解如何進(jìn)行模板數(shù)據(jù)的循環(huán)和控制輸出。
注意,本篇的描述僅針對(duì)使用內(nèi)部模板引擎的情況,如果你使用了Smarty或者其他模板引擎,請(qǐng)參考其相關(guān)的變量輸出語(yǔ)法。
## 循環(huán)輸出
循環(huán)輸出主要是使用volist和foreach標(biāo)簽輸出。
### VOLIST
volist標(biāo)簽通常用于查詢數(shù)據(jù)集(select方法)的結(jié)果輸出,通常模型的select方法返回的結(jié)果是一個(gè)二維數(shù)組,可以直接使用volist標(biāo)簽進(jìn)行輸出。
在控制器中首先對(duì)模版賦值:
~~~
$User = M('User');
$list = $User->limit(10)->select();
$this->assign('list',$list);
~~~
在模版定義如下,循環(huán)輸出用戶的編號(hào)和姓名:
~~~
<volist name="list" id="vo">
{$vo.id}:{$vo.name}<br/>
</volist>
~~~
Volist標(biāo)簽的`name屬性`表示模板賦值的變量名稱,因此不可隨意在模板文件中改變。`id`表示當(dāng)前的循環(huán)變量,可以隨意指定,但確保不要和name屬性沖突,例如:
~~~
<volist name="list" id="data">
{$data.id}:{$data.name}<br/>
</volist>
~~~
支持輸出查詢結(jié)果中的部分?jǐn)?shù)據(jù),例如輸出其中的第5~15條記錄
~~~
<volist name="list" id="vo" offset="5" length='10'>
{$vo.name}
</volist>
~~~
輸出偶數(shù)記錄
~~~
<volist name="list" id="vo" mod="2" >
<eq name="mod" value="1">{$vo.name}</eq>
</volist>
~~~
Mod屬性還用于控制一定記錄的換行,例如:
~~~
<volist name="list" id="vo" mod="5" >
{$vo.name}
<eq name="mod" value="4"><br/></eq>
</volist>
~~~
為空的時(shí)候輸出提示:
~~~
<volist name="list" id="vo" empty="暫時(shí)沒(méi)有數(shù)據(jù)" >
{$vo.id}|{$vo.name}
</volist>
~~~
empty屬性不支持直接傳入html語(yǔ)法,但可以支持變量輸出,例如:
~~~
$this->assign('empty','<span class="empty">沒(méi)有數(shù)據(jù)</span>');
$this->assign('list',$list);
~~~
然后在模板中使用:
~~~
<volist name="list" id="vo" empty="$empty" >
{$vo.id}|{$vo.name}
</volist>
~~~
模板中可以直接使用函數(shù)設(shè)定數(shù)據(jù)集,而不需要在控制器中給模板變量賦值傳入數(shù)據(jù)集變量,如:
~~~
<volist name=":fun('arg')" id="vo">
{$vo.name}
</volist>
~~~
### FOREACH
除了volist標(biāo)簽之外,還可以使用foreach標(biāo)簽,foreach標(biāo)簽類似與volist標(biāo)簽,只是更加簡(jiǎn)單,沒(méi)有太多額外的屬性,例如:
~~~
<foreach name="list" item="vo">
{$vo.id}:{$vo.name}
</foreach>
~~~
name表示數(shù)據(jù)源 item表示循環(huán)變量。
foreach標(biāo)簽還可以輸出一維數(shù)組,例如:
~~~
<foreach name="list" item="vo" >
{$key}|{$vo}
</foreach>
~~~
## 條件輸出
條件輸出最常用的包括switch、if以及eq等比較標(biāo)簽。
### SWITCH
用法:
~~~
<switch name="變量" >
<case value="值1" break="0或1">輸出內(nèi)容1</case>
<case value="值2">輸出內(nèi)容2</case>
<default />默認(rèn)情況
</switch>
~~~
使用方法如下:
~~~
<switch name="User.level">
<case value="1">value1</case>
<case value="2">value2</case>
<default />default
</switch>
~~~
其中name屬性可以使用函數(shù)以及系統(tǒng)變量,例如:
~~~
<switch name="Think.get.userId|abs">
<case value="1">admin</case>
<default />default
</switch>
~~~
對(duì)于case的value屬性可以支持多個(gè)條件的判斷,使用”|”進(jìn)行分割,例如:
~~~
<switch name="Think.get.type">
<case value="gif|png|jpg">圖像格式</case>
<default />其他格式
</switch>
~~~
表示如果$_GET["type"] 是gif、png或者jpg的話,就判斷為圖像格式。
Case標(biāo)簽還有一個(gè)break屬性,表示是否需要break,默認(rèn)是會(huì)自動(dòng)添加break,如果不要break,可以使用:
~~~
<switch name="Think.get.userId|abs">
<case value="1" break="0">admin</case>
<case value="2">admin</case>
<default />default
</switch>
~~~
也可以對(duì)case的value屬性使用變量,例如:
~~~
<switch name="User.userId">
<case value="$adminId">admin</case>
<case value="$memberId">member</case>
<default />default
</switch>
~~~
### 比較標(biāo)簽
比較標(biāo)簽用于簡(jiǎn)單的變量比較,復(fù)雜的判斷條件可以用if標(biāo)簽替換,比較標(biāo)簽是一組標(biāo)簽的集合,基本上用法都一致,如下:
~~~
<比較標(biāo)簽 name="變量" value="值">
內(nèi)容
</比較標(biāo)簽>
~~~
系統(tǒng)支持的比較標(biāo)簽以及所表示的含義分別是:
|標(biāo)簽|含義|
|-----------|-----------------|
|eq或者 equal| 等于 |
|neq 或者notequal| 不等于 |
|gt |大于 |
|egt |大于等于 |
|lt |小于 |
|elt |小于等于 |
|heq |恒等于 |
|nheq |不恒等于 |
他們的用法基本是一致的,區(qū)別在于判斷的條件不同,并且所有的比較標(biāo)簽都可以和else標(biāo)簽一起使用。
例如,要求name變量的值等于value就輸出,可以使用:
~~~
<eq name="name" value="value">value</eq>
~~~
或者
~~~
<equal name="name" value="value">value</equal>
~~~
也可以支持和else標(biāo)簽混合使用:
~~~
<eq name="name" value="value">
相等
<else/>
不相等
</eq>
~~~
當(dāng) name變量的值大于5就輸出
~~~
<gt name="name" value="5">value</gt>
~~~
當(dāng)name變量的值不小于5就輸出
~~~
<egt name="name" value="5">value</egt>
~~~
比較標(biāo)簽中的變量可以支持對(duì)象的屬性或者數(shù)組,甚至可以是系統(tǒng)變量,例如:
當(dāng)vo對(duì)象的屬性(或者數(shù)組,或者自動(dòng)判斷)等于5就輸出
~~~
<eq name="vo.name" value="5">
{$vo.name}
</eq>
~~~
當(dāng)vo對(duì)象的屬性等于5就輸出
~~~
<eq name="vo:name" value="5">
{$vo.name}
</eq>
~~~
當(dāng)$vo['name']等于5就輸出
~~~
<eq name="vo['name']" value="5">
{$vo.name}
</eq>
~~~
而且還可以支持對(duì)變量使用函數(shù)
當(dāng)vo對(duì)象的屬性值的字符串長(zhǎng)度等于5就輸出
~~~
<eq name="vo:name|strlen" value="5">{$vo.name}</eq>
~~~
變量名可以支持系統(tǒng)變量的方式,例如:
~~~
<eq name="Think.get.name" value="value">相等<else/>不相等</eq>
~~~
通常比較標(biāo)簽的值是一個(gè)字符串或者數(shù)字,如果需要使用變量,只需要在前面添加“$”標(biāo)志:
當(dāng)vo對(duì)象的屬性等于$a就輸出
~~~
<eq name="vo:name" value="$a">{$vo.name}</eq>
~~~
## 范圍判斷標(biāo)簽
范圍判斷標(biāo)簽包括`in`、`notin`、`between`和`notbetween`四個(gè)標(biāo)簽,都用于判斷變量是否中某個(gè)范圍。
### IN和NOTIN
用法:
假設(shè)我們中控制器中給id賦值為1:
~~~
$id = 1;
$this->assign('id',$id);
~~~
我們可以使用in標(biāo)簽來(lái)判斷模板變量是否在某個(gè)范圍內(nèi),例如:
~~~
<in name="id" value="1,2,3">
id在范圍內(nèi)
</in>
~~~
最后會(huì)輸出:`id在范圍內(nèi)`。
如果判斷不在某個(gè)范圍內(nèi),可以使用:
~~~
<notin name="id" value="1,2,3">
id不在范圍內(nèi)
</notin>
~~~
可以把上面兩個(gè)標(biāo)簽合并成為:
~~~
<in name="id" value="1,2,3">
id在范圍內(nèi)
<else/>
id不在范圍內(nèi)
</in>
~~~
name屬性還可以支持直接判斷系統(tǒng)變量,例如:
~~~
<in name="Think.get.id" value="1,2,3">
$_GET['id'] 在范圍內(nèi)
</in>
~~~
value屬性也可以使用變量,例如:
~~~
<in name="id" value="$range">
id在范圍內(nèi)
</in>
~~~
$range變量可以是數(shù)組,也可以是以逗號(hào)分隔的字符串。
### BETWEEN 和 NOTBETWEEN
可以使用between標(biāo)簽來(lái)判斷變量是否在某個(gè)區(qū)間范圍內(nèi),可以使用:
~~~
<between name="id" value="1,10">
輸出內(nèi)容1
</between>
~~~
同樣,可以使用notbetween標(biāo)簽來(lái)判斷變量不在某個(gè)范圍內(nèi):
~~~
<notbetween name="id" value="1,10">
輸出內(nèi)容2
</notbetween>
~~~
也可以使用else標(biāo)簽把兩個(gè)用法合并,例如:
~~~
<between name="id" value="1,10">
輸出內(nèi)容1
<else/>
輸出內(nèi)容2
</between>
~~~
當(dāng)使用between標(biāo)簽的時(shí)候,value只需要一個(gè)區(qū)間范圍,也就是只支持兩個(gè)值,后面的值無(wú)效,例如
~~~
<between name="id" value="1,3,10">
輸出內(nèi)容1
</between>
~~~
實(shí)際判斷的范圍區(qū)間是`1~3`,而不是`1~10`,也可以支持字符串判斷,例如:
~~~
<between name="id" value="A,Z">
輸出內(nèi)容1
</between>
~~~
name屬性可以直接使用系統(tǒng)變量,例如:
~~~
<between name="Think.post.id" value="1,5">
輸出內(nèi)容1
</between>
~~~
value屬性也可以使用變量,例如:
~~~
<between name="id" value="$range">
輸出內(nèi)容1
</between>
~~~
## 賦值判斷標(biāo)簽
可以使用present、empty等標(biāo)簽進(jìn)行賦值判斷輸出。
present標(biāo)簽用于判斷某個(gè)變量是否已經(jīng)定義,用法:
~~~
<present name="name">
name已經(jīng)賦值
<else />
name還沒(méi)有賦值
</present>
~~~
name屬性可以直接使用系統(tǒng)變量,例如:
~~~
<present name="Think.get.name">
$_GET['name']已經(jīng)賦值
</present>
~~~
empty標(biāo)簽用于判斷某個(gè)變量是否為空,用法:
<empty name="name">
name為空
<else />
name不為空
</empty>
name屬性可以直接使用系統(tǒng)變量,例如:
~~~
<empty name="Think.get.name">
$_GET['name']為空值
</empty>
~~~
DEFINED標(biāo)簽用于判斷某個(gè)常量是否有定義,用法如下:
~~~
<defined name="NAME">
NAME常量已經(jīng)定義
<else />
NAME常量未定義
</defined>
~~~
## 原生代碼
Php代碼可以和標(biāo)簽在模板文件中混合使用,可以在模板文件里面書(shū)寫(xiě)任意的PHP語(yǔ)句代碼 ,包括下面兩種方式:
### 第一種:使用php標(biāo)簽
例如:
~~~
<php>echo 'Hello,world!';</php>
~~~
我們建議需要使用PHP代碼的時(shí)候盡量采用php標(biāo)簽,因?yàn)樵腜HP語(yǔ)法可能會(huì)被配置禁用而導(dǎo)致解析錯(cuò)誤。
### 第二種:使用原生php代碼
~~~
<?php echo 'Hello,world!'; ?>
~~~
## 總結(jié)
本章我們講述了模板中進(jìn)行循環(huán)和控制輸出,下一篇我們還會(huì)講述如何使用公共模板和布局模板來(lái)簡(jiǎn)化模板文件的定義。
- 快速入門(mén) 1:基礎(chǔ)
- 快速入門(mén) 2:CURD
- 快速入門(mén) 3:查詢語(yǔ)言
- 快速入門(mén) 4:連貫操作
- 快速入門(mén) 5:變量
- 快速入門(mén) 6:路由
- 快速入門(mén) 7:視圖
- 快速入門(mén) 8:變量輸出
- 快速入門(mén) 9:循環(huán)和控制輸出
- 快速入門(mén) 10:公共模板和模板布局
- 快速入門(mén) 11:Action參數(shù)綁定
- 快速入門(mén) 12:空操作和空控制器
- 快速入門(mén) 13:初始化、前置和后置操作
- 快速入門(mén) 14:頁(yè)面跳轉(zhuǎn)和重定向
- 快速入門(mén) 15:頁(yè)面請(qǐng)求和AJAX
- 快速入門(mén) 16:偽靜態(tài)
- 快速入門(mén) 17:操作綁定到類
- 快速入門(mén) 18:多層控制器
- 快速入門(mén) 19:自動(dòng)驗(yàn)證
- 快速入門(mén) 20:自動(dòng)完成
