<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0"><tr><th colspan="3" align="center">Smarty - the compiling PHP template engine</th></tr><tr><td width="25%" align="left" valign="bottom"><a href="language.function.for.html" accesskey="P">Prev</a></td> <td width="50%" align="center" valign="bottom">Chapter 7. Built-in Functions[第七章.内置函数]</td> <td width="25%" align="right" valign="bottom"><a href="language.function.function.html" accesskey="N">Next</a></td></tr></table> # {foreach},{foreachelse}遍历 **Table of Contents目录**[@index](#)[@iteration](#)[@first](#)[@last](#)[@show](#)[@total](#) {foreach} is used for looping over arrays of data. {foreach} has a simpler and cleaner syntax than the {section} loop, and can also loop over associative arrays. {foreach $arrayvar as $itemvar} {foreach $arrayvar as $keyvar=>$itemvar} <table width="80%" border="0" cellpadding="2" cellspacing="2" class="note"><caption> 提示 </caption> <tr><td>Note<br/> This foreach syntax does not accept any named attributes. This syntax is new to Smarty 3, however the Smarty 2.x syntax {foreach from=$myarray key="mykey" item="myitem"} is still supported.<br/> foreach语法不能接受任何属性名,这是Smarty3新增的语法,但Smarty2.x中的{foreach from=$myarray key="mykey" item="myitem"}语法仍受支持。</td> </tr></table> * {foreach} loops can be nested. * The array variable, usually an array of values, determines the number of times {foreach} will loop. You can also pass an integer for arbitrary loops. * {foreachelse} is executed when there are no values in the array variable. * {foreach} properties are @index, @iteration, @first, @last, @show, @total. * Instead of specifying the key variable you can access the current key of the loop item by {$item@key} (see examples below). {foreach}用来遍历数据数组,{foreach}与[{section}](#)循环相比更简单、语法更干净,也可以用来遍历关联数组。 {foreach $arrayvar as $itemvar} {foreach $arrayvar as $keyvar=>$itemvar} {foreach}循环可以嵌套; 数组变量通常是(另)一个数组的值,用来指导循环的次数,你可以为循环传递一个整数; 当数组变量无值时执行{foreachelse}; {foreach}的属性是@index、@iteration、@first、@last、@show、@total; 可以用循环项目中的当前键({$item@key})代替键值变量(参见下例)。 <table width="80%" border="0" cellpadding="2" cellspacing="2" class="note"><caption> 提示 </caption> <tr><td>Note<br/> The $var@property syntax is new to Smarty 3, however when using the Smarty 2 {foreach from=$myarray key="mykey" item="myitem"} style syntax, the $smarty.foreach.name.property syntax is still supported.<br/> $var@property是Smarty3的新语法,但使用Smarty2的{foreach from=$myarray key="mykey" item="myitem"}风格语法时$smarty.foreach.name.property语法仍然受支持。</td> </tr></table> <table width="80%" border="0" cellpadding="2" cellspacing="2" class="note"><caption> 提示 </caption> <tr><td>Note<br/> Although you can retrieve the array key with the syntax {foreach $myArray as $myKey=&gt; $myValue}, the key is always available as $myValue@key within the foreach loop. <br/> 虽然你可以用{foreach $myArray as $myKey=&gt; $myValue}检索数组键,但foreach循环中的$myValue@key仍然有效。</td> </tr></table> **Option Flags: ** | Name | Description | |-----|-----| | from | Disables caching of the {foreach} loop | **选项标记:** | 名称 | 描述 | |-----|-----| | from | {foreach}循环不能缓存 | <table width="100%" border="0" cellpadding="0" cellspacing="0" class="EXAMPLE"><tr><td><div class="EXAMPLE"><a name="AEN2730" id="AEN2730"/> <b><span class="PROGRAMLISTING">Example 7.30. A simple {foreach} loop</span><br/> 例 7-30. {foreach}循环的简单例子</b> <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><pre class="PROGRAMLISTING">&lt;?php$arr = array('red', 'green', 'blue');$smarty-&gt;assign('myColors', $arr);?&gt; Template to output $myColors in an un-ordered list&lt;ul&gt;{foreach $myColors as $color} &lt;li&gt;{$color}&lt;/li&gt;{/foreach}&lt;/ul&gt; The above example will output:&lt;ul&gt; &lt;li&gt;red&lt;/li&gt; &lt;li&gt;green&lt;/li&gt; &lt;li&gt;blue&lt;/li&gt;&lt;/ul&gt;</pre></td></tr></table></div></td></tr></table> <table width="100%" border="0" cellpadding="0" cellspacing="0" class="EXAMPLE"><tr><td><div class="EXAMPLE"> <p><b>Example 7.31. Demonstrates the an additional key variable<br/> 例 7-31. 加了键变量的演示</b></p> <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td> <p>&lt;?php<br/> $people = array('fname' =&gt; 'John', 'lname' =&gt; 'Doe', 'email' =&gt; 'j.doe@example.com');<br/> $smarty-&gt;assign('myPeople', $people);<br/> ?&gt;<br/><br/> Template to output $myArray as key/value pairs. //键值对 <br/> &lt;ul&gt;<br/> {foreach $myPeople as $value}<br/> &lt;li&gt;{$value@key}: {$value}&lt;/li&gt;<br/> {/foreach}<br/> &lt;/ul&gt;<br/><br/> The above example will output:</p> <p>&lt;ul&gt;<br/> &lt;li&gt;fname: John&lt;/li&gt;<br/> &lt;li&gt;lname: Doe&lt;/li&gt;<br/> &lt;li&gt;email: j.doe@example.com&lt;/li&gt;<br/> &lt;/ul&gt;</p> </td></tr></table></div></td></tr></table> **Example 7.32. {foreach} with nested item and key 例 7-32. 嵌套了item和key的{foreach}** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> Assign an array to Smarty, the key contains the key for each looped value.<br/> &lt;?php<br/>$smarty-&gt;assign('contacts', array(array('phone' =&gt; '555-555-1234',<br/>'fax' =&gt; '555-555-5678',<br/>'cell' =&gt; '555-555-0357'),<br/>array('phone' =&gt; '800-555-4444',<br/>'fax' =&gt; '800-555-3333',<br/>'cell' =&gt; '800-555-2222')<br/>));<br/>?&gt;<br/><br/>The template to output $contact.<br/>{* key always available as a property *} //{*键常常是个有效属性*} <br/>{foreach $contacts as $contact}<br/>{foreach $contact as $value}<br/>{$value@key}: {$value}<br/>{/foreach}<br/>{/foreach}<br/>{* accessing key the PHP syntax alternate *} //{* 交替php语法访问键 *} <br/>{foreach $contacts as $contact}<br/>{foreach $contact as $key =&gt; $value}<br/>{$key}: {$value}<br/>{/foreach}<br/>{/foreach}<br/><br/>Either of the above examples will output:<br/>phone: 555-555-1234<br/>fax: 555-555-5678<br/>cell: 555-555-0357<br/>phone: 800-555-4444<br/>fax: 800-555-3333<br/>cell: 800-555-2222 </p> </td> </tr></table> **Example 7.33. Database example with {foreachelse} 例 7-33. {foreachelse}的演示例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> A database (PDO) example of looping over search results. This example is looping over a PHP iterator instead of an array().<br/><span class="STYLE2">一个遍历数据库(PDO)搜索结果的例子,本例是用php迭代器代替数组遍历。</span><br/> &lt;?php <br/>include('Smarty.class.php'); <br/>$smarty = new Smarty; <br/>$dsn = 'mysql:host=localhost;dbname=test'; <br/>$login = 'test'; <br/>$passwd = 'test'; <br/>// setting PDO to use buffered queries in mysql is <br/>// important if you plan on using multiple result cursors <br/>// in the template.<br/>//如果你打算在模版中使用多重查询结果游标,那么使用mysql时设置PDO的缓冲查询是非常重要的。<br/> $db = new PDO($dsn, $login, $passwd, array( <br/> PDO::MYSQL_ATTR_USE_BUFFERED_QUERY =&gt; true)); <br/> $res = $db-&gt;prepare("select * from users"); <br/> $res-&gt;execute(); <br/> $res-&gt;setFetchMode(PDO::FETCH_LAZY); <br/> // assign to smarty <br/> $smarty-&gt;assign('res',$res); <br/> $smarty-&gt;display('index.tpl');?&gt;<br/> ?&gt;<br/><br/> {foreach $res as $r} <br/> {$r.id} <br/> {$r.name}<br/> {foreachelse}<br/> .. no results .. <br/> {/foreach}</p> </td> </tr></table> The above is assuming the results contain the columns named id and name. What is the advantage of an iterator vs. looping over a plain old array? With an array, all the results are accumulated into memory before being looped. With an iterator, each result is loaded/released within the loop. This saves processing time and memory, especially for very large result sets. 上述(例子)假设了结果中包含了id、name列。 迭代器PK遍历简朴老旧数组的优势在哪?对于数组,循环结束前所有结果都累积到内存中;对于迭代器,循环时每一结果都重复装载/释放的过程,这样减少了处理时间和内存消耗,特别是对于巨型结果集。   @index index contains the current array index, starting with zero. 包含当前数组的下标,开始时为0。 **Example 7.34. index example 例 7-34. index例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> {* output empty row on the 4th iteration (when index is 3) *}<br/> &lt;table&gt;<br/> {foreach $items as $i}<br/>{if $i@index eq 3}<br/>{* put empty table row *}<br/>&lt;tr&gt;&lt;td&gt;nbsp;&lt;/td&gt;&lt;/tr&gt;<br/>{/if}<br/>&lt;tr&gt;&lt;td&gt;{$i.label}&lt;/td&gt;&lt;/tr&gt;<br/>{/foreach}<br/>&lt;/table&gt;</p></td> </tr></table>   @iteration iteration contains the current loop iteration and always starts at one, unlike index. It is incremented by one on each iteration. iteration包含当前循环的迭代,总是以1开始,这点与index不同。每迭代一次值自动加1。 **Example 7.35. iteration example: is div by ****例 7-35. iteration例子 :is div by ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> The "is div by" operator can be used to detect a specific iteration. Here we bold-face the name every 4th iteration.<br/> "is div by"操作符可能用来侦察特殊迭代,这里每迭代4次时name用粗黑字体显示。 <br/> {foreach $myNames as $name}<br/>{if $name@iteration is div by 4}<br/>&lt;b&gt;{$name}&lt;/b&gt;<br/>{/if}<br/>{$name}<br/>{/foreach}</p></td> </tr></table> **Example 7.36. iteration example: is even/odd by ****例 7-36. iteration例子 :is even/odd by ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> The "is even by" and "is odd by" operators can be used to alternate something every so many iterations.<br/> Choosing between even or odd rotates which one starts. Here we switch the font color every 3rd iteration.<br/> "is even by"和"is odd by"操作符可以用来在每多少迭代时交替什么什么...。<br/> 当奇数或偶数开始时选择even或odd中的一个来交替,这里我们选择每迭代3次时更改显示颜色。</p> <p> <br/> {foreach $myNames as $name}<br/> {if $name@iteration is even by 3}<br/> &lt;span style="color: #000"&gt;{$name}&lt;/span&gt;<br/> {else}<br/> &lt;span style="color: #eee"&gt;{$name}&lt;/span&gt;<br/> {/if}<br/> {/foreach}<br/><br/><br/> This will output something similar to this:<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #000"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> &lt;span style="color: #eee"&gt;...&lt;/span&gt;<br/> ...</p></td> </tr></table>   @first first is TRUE if the current {foreach} iteration is the initial one. Here we display a table header row on the first iteration. 当{foreach}循环第一个时first为真。这里我们演示当第一次迭代表格头所在行。 **Example 7.37. first property example ****例 7-37. first属性的例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> {* show table header at first iteration *}<br/> &lt;table&gt;<br/> {foreach $items as $i}<br/>{if $i@first}<br/>&lt;tr&gt;<br/>&lt;th&gt;key&lt;/td&gt;<br/>&lt;th&gt;name&lt;/td&gt;<br/>&lt;/tr&gt;<br/>{/if}<br/>&lt;tr&gt;<br/>&lt;td&gt;{$i@key}&lt;/td&gt;<br/>&lt;td&gt;{$i.name}&lt;/td&gt;<br/>&lt;/tr&gt;<br/>{/foreach}<br/>&lt;/table&gt;</p></td> </tr></table>   @last last is set to TRUE if the current {foreach} iteration is the final one. Here we display a horizontal rule on the last iteration. 当{foreach}迭代到最后时last为真。这里我们演示当迭代到最后时显示一条横线。 **Example 7.38. last property example ****例 7-38. last属性的例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> {* Add horizontal rule at end of list *}<br/> {foreach $items as $item}<br/>&lt;a href="#{$item.id}"&gt;{$item.name}&lt;/a&gt;{if $prod@last}&lt;hr&gt;{else},{/if}<br/>{foreachelse}<br/>... no items to loop ...<br/>{/foreach}</p></td> </tr></table>   @show The show* show* property can be used after the execution of a {foreach} loop to detect if data has been displayed or not. show is a boolean value. *show*属性用在检测{foreach}循环是否无数据显示,show是个布尔值(true or false)。 **Example 7.39. show property example ****例 7-39. showt属性的例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p>&lt;ul&gt;<br/> {foreach $myArray as $name}<br/>&lt;li&gt;{$name}&lt;/li&gt;<br/>{/foreach}<br/>&lt;/ul&gt;<br/>{if $name@show} do something here if the array contained data {/if}</p></td> </tr></table>   @total total contains the number of iterations that this {foreach} will loop. This can be used inside or after the {foreach}. total包含{foreach}循环的总数(整数),可以用在{forach}里面或后面。 **Example 7.40. total property example ****例 7-39. total属性的例子 ** <table border="0" bgcolor="#E0E0E0" width="100%"><tr><td><p> {* show number of rows at end *} //{* 最后显示总行数 *} <br/> {foreach $items as $item}<br/>{$item.name}&lt;hr/&gt;<br/>{if $prod@last}<br/>&lt;div id="total"&gt;{$prod@total} items&lt;/div&gt;<br/>{/if}<br/>{foreachelse}<br/>... no items to loop ...<br/>{/foreach}</p></td> </tr></table> 参见[{section}](#)和[{for}](#)。 <table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0"><tr><td width="33%" align="left" valign="top"><a href="language.function.for.html" accesskey="P">Prev</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">Home</a></td><td width="33%" align="right" valign="top"><a href="language.function.function.html" accesskey="N">Next</a></td></tr><tr><td width="33%" align="left" valign="top">{for}<br/> 循环</td><td width="34%" align="center" valign="top"><a href="language.builtin.functions.html" accesskey="U">Up</a></td><td width="33%" align="right" valign="top">{function}<br/> 函数</td></tr></table>