{foreach $arrayvar as $itemvar}

    {foreach $arrayvar as $keyvar=>$itemvar}

    foreach的语法可以接受没有名称的属性,该语法是Smarty 3新增的。然而Smarty 2语法 {foreach from=$myarray key="mykey" item="myitem"}也同样支持。

    • {foreach} 循环可以被嵌套使用.

    • array变量,一般是数组的值,决定了{foreach} 循环的次数。你也可以传递一个任意的整数来控制循环次数。

    • 如果array数组变量中,没有值的情况下, {foreachelse}将执行。

    • {foreach}的属性: , @iteration, , @last, , @total.

    • {foreach}的语法命令: , {continue}.

    • 代替指定key变量,你可以通过{$item@key}来使用循环的当前key。(见下面的例子).

    Note

    的语法是Smarty 3新增的。然而Smarty 2风格的语法{foreach from=$myarray key="mykey" item="myitem"}, $smarty.foreach.name.property也是支持的。

    Note

    即使你在循环语法里{foreach $myArray as $myKey => $myValue} 已经指定了key的变量名,但循环体内$myValue还是可用的。

    可选标记:


    Example 7.30. 简单的{foreach} 循环

    模板将顺序输出$myColors

    1. <ul>
    2. {foreach $myColors as $color}
    3. <li>{$color}</li>
    4. {/foreach}
    5. </ul>
    6.  

    输出:

    1. <ul>
    2. <li>red</li>
    3. <li>green</li>
    4. <li>blue</li>
    5. </ul>
    6.  
    1. <?php
    2. $people = array('fname' => 'John', 'lname' => 'Doe', 'email' => 'j.doe@example.com');
    3. $smarty->assign('myPeople', $people);
    4. ?>
    5.  

    模板将以键值对的方式输出$myArray

    1. <ul>
    2. {foreach $myPeople as $value}
    3. <li>{$value@key}: {$value}</li>
    4. {/foreach}
    5. </ul>
    6.  

    输出:

    1. <ul>
    2. <li>fname: John</li>
    3. <li>lname: Doe</li>
    4. <li>email: j.doe@example.com</li>
    5. </ul>
    6.  


    Example 7.32. 多维数组通过itemkey来嵌套使用{foreach}

    多维数组的键一般会对应另一个数组。

    1. <?php
    2. $smarty->assign('contacts', array(
    3. array('phone' => '555-555-1234',
    4. 'fax' => '555-555-5678',
    5. 'cell' => '555-555-0357'),
    6. array('phone' => '800-555-4444',
    7. 'fax' => '800-555-3333',
    8. 'cell' => '800-555-2222')
    9. ));
    10. ?>
    11.  

    模板将输出$contact.

    上面两个例子都会输出:

    1. phone: 555-555-1234
    2. fax: 555-555-5678
    3. cell: 555-555-0357
    4. phone: 800-555-4444
    5. cell: 800-555-2222
    6.  


    Example 7.33. {foreachelse}的数据库例子

    循环显示数据库(PDO)结果。例子是循环了一个PHP的迭代器(iterator)而不是一个数组(array)。

    1. <?php
    2. include('Smarty.class.php');
    3.  
    4. $smarty = new Smarty;
    5.  
    6. $dsn = 'mysql:host=localhost;dbname=test';
    7. $login = 'test';
    8. $passwd = 'test';
    9.  
    10. // setting PDO to use buffered queries in mysql is
    11. // important if you plan on using multiple result cursors
    12. // in the template.
    13.  
    14. $db = new PDO($dsn, $login, $passwd, array(
    15. PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true));
    16.  
    17. $res = $db->prepare("select * from users");
    18. $res->execute();
    19. $res->setFetchMode(PDO::FETCH_LAZY);
    20.  
    21. // assign to smarty
    22. $smarty->assign('res',$res);
    23.  
    24. $smarty->display('index.tpl');?>
    25. ?>
    26.  
    1. {foreach $res as $r}
    2. {$r.id}
    3. {$r.name}
    4. {foreachelse}
    5. .. no results ..
    6. {/foreach}
    7.  

    上面的例子显示了查询结果idname两个字段的内容。

    迭代器和数组循环哪个更高效呢?数组而言,每次循环之前全部的数组数据都会被先放到内存堆栈内,然后再进行循环。 而迭代器每次迭代循环时,都会载入并释放结果内容,这样可以节省运行时间和内存,尤其是当结果集非常大的时候。

    index是当前数组索引,从0开始计算。


    Example 7.34. index 例子

    1. {* output empty row on the 4th iteration (when index is 3) *}
    2. <table>
    3. {foreach $items as $i}
    4. {if $i@index eq 3}
    5. {* put empty table row *}
    6. <tr><td>nbsp;</td></tr>
    7. {/if}
    8. <tr><td>{$i.label}</td></tr>
    9. {/foreach}
    10. </table>
    11.  

    iteration是当前循环的次数,和index不同,iteration是从1开始。 iteration在每次循环的时候都会加一。


    Example 7.35. iteration 例子: is div by

    "is div by"运算可以对循环次数做一些特殊的判断。下面我们将每4次循环就输出一次粗体的名称。

    1. {foreach $myNames as $name}
    2. {if $name@iteration is div by 4}
    3. <b>{$name}</b>
    4. {/if}
    5. {$name}
    6. {/foreach}
    7.  

    "is even by""is odd by"可以用于在循环中奇偶交替进行一些操作。在开始的时候可以选择奇或偶的循环。 下面是每三次循环会改变一次字体颜色。

    1. {foreach $myNames as $name}
    2. {if $name@iteration is even by 3}
    3. <span style="color: #000">{$name}</span>
    4. {else}
    5. <span style="color: #eee">{$name}</span>
    6. {/if}
    7. {/foreach}
    8.  

    输出:

    当循环是首次循环时,first将为TRUE 下面我们用first来显示一个表格的表头。


    Example 7.37. first例子

    1. <table>
    2. {foreach $items as $i}
    3. {if $i@first}
    4. <tr>
    5. <th>key</td>
    6. <th>name</td>
    7. </tr>
    8. {/if}
    9. <tr>
    10. <td>{$i@key}</td>
    11. <td>{$i.name}</td>
    12. </tr>
    13. {/foreach}
    14. </table>
    15.  

    {foreach}循环到了最后一次时, last将为TRUE。 下面我们将在循环的最后插入一条水平线。


    Example 7.38. last例子

    1. {* Add horizontal rule at end of list *}
    2. {foreach $items as $item}
    3. <a href="#{$item.id}">{$item.name}</a>{if $item@last}<hr>{else},{/if}
    4. {foreachelse}
    5. ... no items to loop ...
    6. {/foreach}
    7.  

    show属性是在{foreach}循环执行之后, 检测循环是否显示数据的判断。 show是一个布尔值。


    Example 7.39. show例子

    1. <ul>
    2. {foreach $myArray as $name}
    3. <li>{$name}</li>
    4. {/foreach}
    5. </ul>
    6. {if $name@show} do something here if the array contained data {/if}
    7.  

    @total

    total是整个{foreach}循环的次数。 total可以在{foreach}内部,或者之后使用。


    Example 7.40. total例子

    1. {* show number of rows at end *}
    2. {foreach $items as $item}
    3. {$item.name}<hr/>
    4. {if $item@last}
    5. <div id="total">{$item@total} items</div>
    6. {/if}
    7. {foreachelse}
    8. ... no items to loop ...
    9. {/foreach}
    10.  

    参见{section}, 和 {while}

    {break}停止循环。


    Example 7.41. {break} 例子

    1. {$data = [1,2,3,4,5]}
    2. {foreach $data as $value}
    3. {if $value == 3}
    4. {* abort iterating the array *}
    5. {break}
    6. {/if}
    7. {$value}
    8. {/foreach}
    9. {*
    10. prints: 1 2
    11. *}
    12.  

    {continue}

    {continue}将跳过当前本次循环并进入下一次循环。


    Example 7.42. {continue} 例子

    1. {$data = [1,2,3,4,5]}
    2. {foreach $data as $value}
    3. {if $value == 3}
    4. {* skip this iteration *}
    5. {continue}
    6. {/if}
    7. {$value}
    8. {/foreach}
    9. {*
    10. prints: 1 2 4 5
    11. *}