{foreach},{foreachelse}

{foreach} はデータの配列をループするために使います。{foreach}{section} ループよりもシンプルできれいな構文で、 連想配列をループすることもできます。

{foreach $arrayvar as $itemvar}

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

注意

この foreach 構文は、名前つき属性を受け付けません。この構文は Smarty 3 で新しく導入されたものですが、Smarty 2.x 形式の {foreach from=$myarray key="mykey" item="myitem"} もまだ対応しています。

注意

$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 で取得することができます。

オプションのフラグ

名前 概要
nocache {foreach} ループのキャッシュを無効にする

例 7.30. シンプルな {foreach} ループ


<?php
$arr = array('red', 'green', 'blue');
$smarty->assign('myColors', $arr);
?>

  

$myArray を順序なしリストで出力するテンプレート


<ul>
{foreach $myColors as $color}
    <li>{$color}</li>
{/foreach}
</ul>

  

上の例の出力は次のようになります。


<ul>
    <li>red</li>
    <li>green</li>
    <li>blue</li>
</ul>

  

例 7.31. 追加の key 変数の例


<?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>

  

例 7.32. {foreach} で itemkey をネストする例

配列を Smarty に割り当てます。key にはループする値のキーが含まれます。


<?php
 $smarty->assign('contacts', array(
                             array('phone' => '555-555-1234',
                                   'fax' => '555-555-5678',
                                   'cell' => '555-555-0357'),
                             array('phone' => '800-555-4444',
                                   'fax' => '800-555-3333',
                                   'cell' => '800-555-2222')
                             ));
?>

  

$contact を出力するテンプレート


{* key は常にプロパティとして使えます *}
{foreach $contacts as $contact}
  {foreach $contact as $value}
    {$value@key}: {$value}
  {/foreach}
{/foreach}

{* PHP の構文を使ってキーにアクセスすることもできます *}
{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

  

例 7.33. データベースでの {foreachelse} の例

データベース (PDO) の検索結果をループします。この例は、array() ではなく PHP のイテレータをループします。


<?php 
  include('Smarty.class.php'); 

  $smarty = new Smarty; 

  $dsn = 'mysql:host=localhost;dbname=test'; 
  $login = 'test'; 
  $passwd = 'test'; 

  // テンプレート内で複数の結果カーソルを使う場合は、
  // mysql のバッファクエリを使うように PDO を
  // 設定します

  $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); 

  // Smarty に代入します
  $smarty->assign('res',$res); 

  $smarty->display('index.tpl');?>
?>

  

{foreach $res as $r} 
  {$r.id} 
  {$r.name}
{foreachelse}
  .. 検索結果が見つかりませんでした ..
{/foreach}

  

上の例では、結果に id および name というカラムが含まれることを前提としています。

普通に配列をループさせるのに比べたイテレータの利点は何でしょうか? 配列の場合は、すべての結果をメモリに取り込んでからループが始まります。 イテレータの場合は、ループ内で 1 件ずつ読み込みと解放を繰り返します。 これは、結果セットが巨大な場合は特に、処理時間とメモリの節約になるでしょう。

@index

index には、現在の配列のインデックスをゼロから数えた値が含まれます。

例 7.34. index の例


{* 4 回目の反復 (index が 3 のとき) に空の行を出力します *}
<table>
{foreach $items as $i}
  {if $i@index eq 3}
     {* 空の行を出力します *}
     <tr><td>nbsp;</td></tr>
  {/if}
  <tr><td>{$i.label}</td></tr>
{/foreach}
</table>

  

@iteration

iteration は現在のループが反復された回数を表示します。 index とは異なり、常に 1 から始まります。 各ループごとに 1 ずつ加算されます。

例 7.35. iteration の例: is div by

"is div by" 演算子を使うと、特定の回数を検出することができます。 これは、4 件おきに名前を太字にする例です。


{foreach $myNames as $name}
  {if $name@iteration is div by 4}
    <b>{$name}</b>
  {/if}
  {$name}
{/foreach}

例 7.36. iteration の例: is even/odd by

"is even by" 演算子と "is odd by" 演算子を使うと、 特定の件数ごとに何かを切り替えることができます。 even と odd で、どちらから始まるかが切り替わります。 これは、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

first は、現在の {foreach} の反復が最初のものであるときに TRUE となります。 ここでは、最初の反復時にテーブルのヘッダを表示します。

例 7.37. first プロパティの例


{* 最初の項目にはテーブルのヘッダを表示します *}
<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

last は、現在の {foreach} の反復が最後のものであるときに TRUE となります。 この例では、最後の反復に横罫線を表示します。

例 7.38. last プロパティの例


{* 一覧の最後に横罫線を追加します *}
{foreach $items as $item}
  <a href="#{$item.id}">{$item.name}</a>{if $item@last}<hr>{else},{/if}
{foreachelse}
  ... コンテンツ ...
{/foreach}

  

@show

show{foreach} のパラメータとして使用します。 show は boolean 値です。 FALSE の場合は {foreach} は表示されません。

例 7.39. show プロパティの例


<ul>
{foreach $myArray as $name}
    <li>{$name}</li>
{/foreach}
</ul>
{if $name@show} 配列にデータが含まれている場合にここで何かをします {/if}

@total

total には、 {foreach} がループするトータル回数が含まれます。 これは、{foreach} の内部だけではなく ループを抜けた後でも使用できます。

例 7.40. total プロパティの例


{* 返された行の総数を最後に表示します *}
{foreach $items as $item}
  {$item.name}<hr/>
  {if $item@last}
    <div id="total">{$item@total} items</div>
  {/if}
{foreachelse}
 ... 別の内容 ...
{/foreach}

{section}{for} および {while} も参照ください。

{break}

{break} は、配列の処理を途中で止めます。

例 7.41. {break} の例

 
  {$data = [1,2,3,4,5]}
  {foreach $data as $value}
    {if $value == 3}
      {* 配列の処理を終了します *}
      {break}
    {/if}
    {$value}
  {/foreach}
  {*
    出力は、1 2
  *}
 
   

{continue}

{continue} は、現在のループでその後の処理を省略して次のループに進みます。

例 7.42. {continue} の例

 
  {$data = [1,2,3,4,5]}
  {foreach $data as $value}
    {if $value == 3}
      {* この処理をスキップします *}
      {continue}
    {/if}
    {$value}
  {/foreach}
  {*
    出力は、1 2 4 5
  *}