前回は、PHPのテンプレートエンジンとして広く利用されている「Smarty」を取り上げました。Smartyを活用すれば、foreachによるループ処理や連想配列などを利用し、ロジックとデザインを分離することができます。
 今回はこれを踏まえて、第10回までに作成してきた「簡易オンラインストア」のロジックとデザインを、Smartyを用いて分離します。また、テンプレートを動的に切り替えることで、携帯電話用コンテンツとPC用コンテンツの両方を同時に実現する方法を紹介します。
 前回は、foreachによるループ処理と連想配列、入れ子といった基本構文を紹介しました。引き続きSmartyのテンプレートを見ていきましょう。
 ロジックとデザインを切り離すことで、ロジックやデザインの再利用性も高まります。例えば、PCや携帯電話などそれぞれの端末の種類に特化したテンプレートを用意しておき、ロジック側でブラウザの種類を判別し、それに基づき適切なテンプレートを選択するといった利用が可能です。
 では、sample5.phpを基に、動的にテンプレートを切り替える方法を見ていきましょう。
  
    
      18  //連想配列の配列化 
  19  $data = array( 
  20        array("name"=>"半熟卵のMySQL風チキンドリア","price"=>"850円","qty"=>"5"), 
  21        array("name"=>"地鶏とキノコのBIND9風フェットチーネ","price"=>"780円","qty"=>"4"), 
  22        array("name"=>"有機野菜のApache風グリーンサラダ","price"=>"480円","qty"=>"7") 
  23        ); 
  24 
  25  //テンプレートの変数に値を割り当てる 
  26  $smarty->assign("title", "Smartyサンプル6"); 
  27  $smarty->assign("data", $data); 
  28 
  29 
  30  //ブラウザの種類でテンプレートを切り替え 
  31  //環境変数「HTTP_USER_AGENT」でブラウザを判定 
  32  $agent = $_SERVER['HTTP_USER_AGENT']; 
  33  if(preg_match("/^Mozilla/",$agent) || preg_match("/^Opera/",$agent)){ 
  34       //PC系 
  35     $smarty->display("template6_pc.tpl"); 
  36  }elseif(preg_match("/^SoftBank/",$agent) || preg_match("/^Vodafone/",$agent)){ 
  37       //SoftBank携帯 
  38      $smarty->display("template6_mobile.tpl"); 
  39  }elseif(preg_match("/^DoCoMo/",$agent)){ 
  40       //DoCoMo携帯 
  41      $smarty->display("template6_mobile.tpl"); 
  42  }elseif(preg_match("/^KDDI/",$agent)){ 
  43       //au携帯 
  44      $smarty->display("template6_mobile.tpl"); 
  45  }else{ 
  46       //その他 
  47      $smarty->display("template6_etc.tpl"); 
  48  } 
  49  ?>
     | 
  
      リスト1 smarty6.php
 ブラウザの判定には、環境変数「HTTP_USER_AGENT」を利用します(32行目)。環境変数「HTTP_USER_AGENT」には各ブラウザが発行する「ユーザーエージェントタイプ」が格納されています。その中に特定の文字列が含まれているかどうかによって、各携帯キャリアやPCブラウザの種類を区別します。
 なおサンプルでは、ブラウザタイプにマッチする文字列を簡略化しています(例えば「SoftBnak」では旧J-PHONEが考慮されていないなど)。各キャリアおよびPC系ブラウザのユーザーエージェントタイプの完全な一覧については、この後に紹介するURLを参考にしてください。
 また、環境変数「HTTP_USER_AGENT」はクライアント側で簡単に偽装できるため、過度な使用には注意します。
 文字列の判定にはpreg_match()を使用しています(33、36、39、42行目)。preg_match()では正規表現によるマッチングを利用することができ、柔軟に文字列を扱うことが可能です。サンプルではPC系(template6_pc.tpl)、携帯キャリア系(template6_mobile.tpl)、その他(template6_etc.tpl)の3種類のテンプレートを用意しています。
 PC系テンプレート「template6_pc.tpl」では、使用するアイコンや表示領域を一般的なPCモニタの解像度に合わせたものを利用し、携帯系テンプレート「template6_mobile.tpl」ではアイコンや表示される領域を最小限に、その他のブラウザにはテンプレート「template6_etc.tpl」を使って使用しているブラウザがコンテンツに対応していないことを表示するようにしています。
  
    13  {* PC用コンテンツ *} 
  14  {foreach from=$data item=value01 name=loop01} 
  15      <table width="390" border="0" cellspacing="0" cellpadding="7" height="55" align="center"> 
  16          <tr> 
  17              <td valign="top" width="40"><img src="icon.jpg" width="40" height="60" border="0"></td> 
  18              <td valign="top" width="350"><font size="2"><b>{$value01.name|escape}</b></font><br> 
  19                 <div align="right"><b>¥ {$value01.price|escape}/1個</b> 
  20                 <b>{$value01.qty|escape}個</b></div> 
  21             </td> 
  22          </tr> 
  23      </table> 
  24  {foreachelse} 
  25    表示させるデータがありません。 
  26  {/foreach} 
  27  </table>
     | 
  
  リスト2 templates/template6_pc.tpl(アイコンサイズや表示領域は余裕のあるサイズを指定)
  
    
      13  {* 携帯コンテンツ *} 
    14  {foreach from=$data item=value01 name=loop01} 
    15      <table border="0" align="center" width="100%"> 
    16          <tr> 
    17              <td  width="20" height="30" valign="top"><img src="icon_mini.jpg" width="20" height="30" border="0"></td> 
    18               <td align=left><font size="2"><b>{$value01.name|escape}</b></font><br> 
    19                    <div align="right"><b>¥{$value01.price|escape}/1個 </b> 
    20                  <b>{$value01.qty|escape}個</b></div> 
    21              </td> 
    22         </tr> 
    23      </table> 
    24  {foreachelse} 
    25    表示させるデータがありません。 
    26  {/foreach} 
    27  </table> | 
    
  
  リスト3 templates/template6_mobile.tpl(アイコンサイズや表示領域を最小限に抑え、小さなモニタでも1画面で収まるようにサイズ指定)
  
    
       12  {* ブラウザ未対応 *} 
    13  <div align=center> 
    14  <font size="2">ご使用のブラウザには対応していません。</font> 
    15  </div>
       | 
    
  
  リスト4 templates/template6_etc.tpl(コンテンツが使用しているブラウザには対応していないことを知らせる)
 この結果、ブラウザに応じて、下記の2つの画面が切り替えて表示されるようになります。
画面1 smarty6.phpの動作画面・PC版 
画面2 smarty6.phpの動作画面・携帯版(「iモードHTMLシミュレータII」を使用)