{foreach},{foreachelse}
{foreach}用于遍历数据数组。{foreach}比{section}循环的语法更简单、更清晰,并且还可以遍历关联数组。
选项标志
| 名称 | 描述 |
|---|---|
| nocache | 禁用{foreach}循环的缓存 |
示例
{foreach $arrayvar as $itemvar}
{$itemvar|escape}
{/foreach}
{foreach $arrayvar as $keyvar=>$itemvar}
{$keyvar}: {$itemvar|escape}
{/foreach}
注意
这种 foreach 语法不接受任何命名属性。这种语法是 Smarty 3 的新特性,但是 Smarty 2.x 的语法
{foreach from=$myarray key="mykey" item="myitem"}仍然受支持。
-
{foreach}循环可以嵌套。 -
array变量,通常是值的数组,决定了{foreach}将循环的次数。你也可以传递一个整数进行任意循环。 -
当
array变量中没有值时,执行{foreachelse}。 -
{foreach}的属性有@index,@iteration,@first,@last,@show,@total。 -
{foreach}的构造有{break},{continue}。 -
你可以通过
{$item@key}访问循环项的当前键,而不是指定key变量(见下面的示例)。
注意
$var@property语法是 Smarty 3 的新特性,然而,当使用 Smarty 2 的{foreach from=$myarray key="mykey" item="myitem"}风格的语法时,$smarty.foreach.name.property语法仍然受支持。注意
尽管你可以用
{foreach $myArray as $myKey => $myValue}语法获取数组键,但在 foreach 循环中,键始终以$myValue@key的形式可用。
<?php
$arr = array('red', 'green', 'blue');
$smarty->assign('myColors', $arr);
模板输出$myColors为无序列表
<ul>
{foreach $myColors as $color}
<li>{$color}</li>
{/foreach}
</ul>
上述示例将输出:
<ul>
<li>red</li>
<li>green</li>
<li>blue</li>
</ul>
<?php
$people = array('fname' => 'John', 'lname' => 'Doe', 'email' => 'j.doe@example.com');
$smarty->assign('myPeople', $people);
模板输出$myArray为键值对。
<ul>
{foreach $myPeople as $value}
<li>{$value@key}: {$value}</li>
{/foreach}
</ul>
上述示例将输出:
<ul>
<li>fname: John</li>
<li>lname: Doe</li>
<li>email: j.doe@example.com</li>
</ul>
将数组分配给 Smarty,键包含每个循环值的键。
<?php
$smarty->assign(
'contacts',
[
['phone' => '555-555-1234', 'fax' => '555-555-5678', 'cell' => '555-555-0357'],
['phone' => '800-555-4444', 'fax' => '800-555-3333', 'cell' => '800-555-2222'],
]
);
输出$contact的模板。
{* key always available as a property *}
{foreach $contacts as $contact}
{foreach $contact as $value}
{$value@key}: {$value}
{/foreach}
{/foreach}
{* accessing key the PHP syntax alternate *}
{foreach $contacts as $contact}
{foreach $contact as $key => $value}
{$key}: {$value}
{/foreach}
{/foreach}
上述两个示例都会输出:
phone: 555-555-1234
fax: 555-555-5678
cell: 555-555-0357
phone: 800-555-4444
fax: 800-555-3333
cell: 800-555-2222
数据库(PDO)示例,遍历搜索结果。此示例正在遍历 PHP 迭代器,而不是数组()。
<?php
include('Smarty.class.php');
$smarty = new Smarty;
$dsn = 'mysql:host=localhost;dbname=test';
$login = 'test';
$passwd = 'test';
// setting PDO to use buffered queries in mysql is
// important if you plan on using multiple result cursors
// in the template.
$db = new PDO($dsn, $login, $passwd, array(
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
$res = $db->prepare("select * from users");
$res->execute();
$res->setFetchMode(PDO::FETCH_LAZY);
// assign to smarty
$smarty->assign('res',$res);
$smarty->display('index.tpl');?>
{foreach $res as $r}
{$r.id}
{$r.name}
{foreachelse}
.. no results ..
{/foreach}
以上假定结果包含名为id和name的列。
迭代器与遍历普通旧数组的优势是什么?对于数组,所有的结果在循环之前都被积累到内存中。对于迭代器,每个结果在循环中被加载/释放。这节省了处理时间和内存,尤其是对于非常大的结果集。
@index
index包含当前数组索引,从零开始。
{* output empty row on the 4th iteration (when index is 3) *}
<table>
{foreach $items as $i}
{if $i@index eq 3}
{* put empty table row *}
<tr><td>nbsp;</td></tr>
{/if}
<tr><td>{$i.label}</td></tr>
{/foreach}
</table>
@iteration
iteration包含当前循环的迭代次数,始终从一开始,不像index。它在每次迭代时增加一。
可以使用"is div by"运算符来检测特定的迭代。这里我们在每 4 次迭代时将名字加粗。
{foreach $myNames as $name}
{if $name@iteration is div by 4}
<b>{$name}</b>
{/if}
{$name}
{/foreach}
"is even by"和"is odd by"运算符可以用来在每隔几次迭代时交替某个东西。选择偶数或奇数决定了哪一个开始。这里我们每隔 3 次迭代切换字体颜色。
{foreach $myNames as $name}
{if $name@iteration is even by 3}
<span style="color: #000">{$name}</span>
{else}
<span style="color: #eee">{$name}</span>
{/if}
{/foreach}
这将输出类似于这样的内容:
<span style="color: #000">...</span>
<span style="color: #000">...</span>
<span style="color: #000">...</span>
<span style="color: #eee">...</span>
<span style="color: #eee">...</span>
<span style="color: #eee">...</span>
<span style="color: #000">...</span>
<span style="color: #000">...</span>
<span style="color: #000">...</span>
<span style="color: #eee">...</span>
<span style="color: #eee">...</span>
<span style="color: #eee">...</span>
...
@first
如果当前的{foreach}迭代是初始的,那么first为 TRUE。这里我们在第一次迭代时显示一个表头行。
{* show table header at first iteration *}
<table>
{foreach $items as $i}
{if $i@first}
<tr>
<th>key</td>
<th>name</td>
</tr>
{/if}
<tr>
<td>{$i@key}</td>
<td>{$i.name}</td>
</tr>
{/foreach}
</table>
@last
如果当前的{foreach}迭代是最后一次,那么last被设置为 TRUE。这里我们在最后一次迭代时显示一个水平线。
{* Add horizontal rule at end of list *}
{foreach $items as $item}
<a href="#{$item.id}">{$item.name}</a>{if $item@last}<hr>{else},{/if}
{foreachelse}
... no items to loop ...
{/foreach}
@show
show属性可以在执行{foreach}循环后用来检测是否显示了数据。show是一个布尔值。
<ul>
{foreach $myArray as $name}
<li>{$name}</li>
{/foreach}
</ul>
{if $name@show} do something here if the array contained data {/if}
@total
total包含了这个{foreach}将循环的次数。这可以在{foreach}内部或之后使用。
{* show number of rows at end *}
{foreach $items as $item}
{$item.name}<hr/>
{if $item@last}
<div id="total">{$item@total} items</div>
{/if}
{foreachelse}
... no items to loop ...
{/foreach}
{break}
{break}终止数组的迭代
{$data = [1,2,3,4,5]}
{foreach $data as $value}
{if $value == 3}
{* abort iterating the array *}
{break}
{/if}
{$value}
{/foreach}
{*
prints: 1 2
*}
{continue}
{continue}离开当前迭代并开始下一次迭代。
{$data = [1,2,3,4,5]}
{foreach $data as $value}
{if $value == 3}
{* skip this iteration *}
{continue}
{/if}
{$value}
{/foreach}
{*
prints: 1 2 4 5
*}