Smartyの利用

トップ > PHP入門 > クラスの作成

目次

広告

Smartyとは

Smartyは、PHP用のテンプレートエンジンです。これを利用すると、ロジックとデザインを分離して管理することができます。

一つのPHPファイルにロジックとデザインの両方を書いて作成することも可能ですが、分離することでプログラムの見通しが良くなります。また、プログラマーとデザイナーの分業など、複数の人が制作に関わる場合、特に威力を発揮します。

Smartyの利用方法

Smartyを利用するには、公式サイトからダウンロードしたファイルを、PHPから読み込める場所に設置します。その後、PHPプログラムから require_once 'libs/Smarty.class.php'; のように Smarty.class.php を読み込めばOKです。(Smarty.class.php がSmartyの本体です。)

Smartyの詳細な解説は、以下の公式ページに記載されています。

以下では、Smartyの基本的な使用方法を紹介します。なお、解説はSmarty3をもとに行っています。Smarty2では書き方が異なる箇所があります。

Smartyの基本

以下はSmartyを利用したサンプルです。コードの詳細な意味はともかく、まずは画面に文字を表示するだけのプログラムを作成してみます。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$smarty->assign('test1', 'テスト1です。');
$smarty->assign('test2', 'テスト2です。');
$smarty->assign('test3', 'テスト3です。');

$smarty->display('test.html');

?>

今回はこのファイルの名前は sample.php とします。このファイルに html タグや body タグを書く必要はありません。後ほど用意するテンプレートファイル内に書きます。

また、プログラムと同じフォルダ内に smarty ディレクトリを作成し、その中にSmartyの libs フォルダ内にあるファイルとディレクトリをすべてコピーします。

さらに、templates ディレクトリと compile_dir ディレクトリを作成します。レンタルサーバーで実行する場合、templates_c ディレクトリには書き込み権限を与えておきます。

次にテンプレートを作成します。templates 内に test.html を作成し、以下の内容を記述します。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
  <li>{$test1}</li>
  <li>{$test2}</li>
  <li>{$test3}</li>
</ul>
</body>
</html>

これで準備は完了です。PHPプログラムにアクセスすると、{$test1}{$test3} の部分がそれぞれ テスト1です。テスト3です。 に置き換えられて表示されます。
このように、プログラム部分と表示部分を分割して作成することができるようになります。

なお、ファイルの構成は、一例ですが以下のようになります。

lesson / sample.php
   |
   +-- templates / test.html
   |
   +-- templates_c /
   |
   +-- smarty / debug.tpl
         |      Smarty.class.php
         |
         +-- plugins / ~略~
         |
         +-- sysplugins / ~略~

Smartyの機能

上で紹介したように、Smartyは Smarty.class.php を読み込んでから使用します。このファイルに必要な命令が書かれているので、読み込むことによって色々な命令が利用できるようになります。

Smartyを使用するには、まずは Smarty クラスを呼び出します。具体的には以下のようになります。

$smarty = new Smarty();

これで $smarty にSmartyのオブジェクトが代入されます。以降はこのオブジェクトを参照することで、色々な操作ができるようになります。

テンプレートの格納場所

template_dir プロパティで、テンプレートを格納する場所を指定します。
この指定を行わなかった場合、templates/ を格納場所とみなします。ただし解りやすくするため、明示的にテンプレートの位置を指定したほうがいいでしょう。

compile_dir プロパティで、コンパイル済みテンプレートを格納する場所を指定します。Smartyは毎回テンプレートファイルを解析せず、一度テンプレートを読み込むとPHPプログラムに変換(コンパイル)したものを保存します。次回からは変換済みのPHPプログラムを読み込むため、高速に動作します。
この指定を行わなかった場合、templates_c/ を格納場所とみなします。ただし template_dir と同様、明示的にテンプレートの位置を指定したほうがいいでしょう。

もしプログラムやテンプレートを修正しても表示結果が変わらなかった場合、compile_dir 内のファイルをすべて削除してみてください。PHPプログラムへの変換が再度行われます。

変数の割り当て

assign メソッドで、テンプレート上の変数に対して値を割り当てることができます。例えば

$smarty->assign('test1', 'テスト1です。');

と書くと、テンプレートの {$test1}テスト1です。 に置換されます。変数の割り当ては

$smarty->assign(array(
  'test1' => 'テスト1です。',
  'test2' => 'テスト2です。',
  'test3' => 'テスト3です。'
));

このように array で一度に行うこともできます。

テンプレートの表示

display メソッドで、テンプレートを読み込んで表示することができます。例えば

$smarty->display('test.html');

と書くと、template_dir で指定した場所にある test.html をテンプレートとして読み込み、表示します。表示の際、assign で割り当てた変数が置換されます。

このように、Smartyを利用すればプログラム部分とデザイン部分を切り離して作成することができます。上のような短いブログラムの場合はあまりメリットが感じられないかもしれませんが、複雑なプログラムになってくると非常に有効になります。

配列と連想配列

assign は変数だけでなく、配列を割り当てることもできます。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$fruits = array('リンゴ', 'ミカン', 'ブドウ');

$smarty->assign('fruits', $fruits);

$smarty->display('test.html');

?>

テンプレート側では、{$fruits[0]}{$fruits[1]} で配列の内容を参照することができます。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
  <li>{$fruits[0]}</li>
  <li>{$fruits[1]}</li>
  <li>{$fruits[2]}</li>
</ul>
</body>
</html>

assign は連想配列を割り当てることもできます。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$fruits = array('apple' => 'リンゴ', 'orange' => 'ミカン', 'grape' => 'ブドウ');

$smarty->assign('fruits', $fruits);

$smarty->display('test.html');

?>

テンプレート側では、{$fruits.apple}{$fruits.orange} で連想配列の内容を参照することができます。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
  <li>{$fruits.apple}</li>
  <li>{$fruits.orange}</li>
  <li>{$fruits.grape}</li>
</ul>
</body>
</html>

条件分岐

Smartyでは、テンプレートに簡単な条件分岐や制御文を書くことができます。

Smartyを利用するのはロジックとデザインの分離が目的なので、テンプレートに複雑なロジックを書くのは本末転倒です。ですが、条件に応じて表示内容を切り替える場合など、デザインに関する簡単なロジックはテンプレート側で制御できると便利です。

以下は条件分岐の例です。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$smarty->assign('sample', 10);

$smarty->display('test.html');

?>

あらかじめ sample10 を割り当てています。特に新しい事はありません。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
{if $sample == 10}<p>変数sampleの内容は10です。</p>
{elseif $sample > 5}<p>変数sampleの内容は5より大きいです。</p>
{else}<p>変数sampleの内容は5より小さいです。</p>
{/if}
</body>
</html>

このように ifelseifelse を使用することができます。比較の方法などはPHPと同じです。

繰り返し

Smartyでは処理の繰り返しも制御することができます。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$fruits = array('リンゴ', 'ミカン', 'ブドウ');

$smarty->assign('fruits', $fruits);

$smarty->display('test.html');

?>

あらかじめ fruits に 配列を割り当てています。特に新しい事はありません。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
  {foreach $fruits as $fruit}
  <li>{$fruit}</li>
  {/foreach}
</ul>
</body>
</html>

これを実行すると、リンゴミカンブドウ がそれぞれリストで表示されます。

PHPの foreach と同様、配列 $fruits の内容が先頭から順に $fruit という変数に代入され、繰り返し処理されていきます。

以下のようにすると、連想配列に対して繰り返し処理もできます。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$fruits = array('apple' => 'リンゴ', 'orange' => 'ミカン', 'grape' => 'ブドウ');

$smarty->assign('fruits', $fruits);

$smarty->display('test.html');

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<ul>
  {foreach $fruits as $key => $value}
  <li>{$key} ... {$value}</li>
  {/foreach}
</ul>
</body>
</html>

PHPの foreach と同様、配列 $fruits のキーと値が先頭から順に $key$value という変数に代入され、繰り返し処理されていきます。

修飾子

修飾子を使用すれば、assign で割り当てた内容に変更を加えることができます。例えば

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$smarty->assign('test', "テスト。\nこれは<em>テスト</em>です。");

$smarty->display('test.html');

?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test}</p>
</body>
</html>

このようなプログラムとテンプレートがあった場合、{$test} の内容は

テスト。
これは<em>テスト</em>です。

になります。ですが <br /> タグによる改行ではなく普通の改行なので、表示結果では改行が反映されません。

もし改行を反映させたければ、PHP側で nl2br を使用すればOKです。ですがこのような表示に関する簡単な制御は、テンプレート側で指定できるようになっています。具体的には

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test|nl2br}</p>
</body>
</html>

このように書きます。テンプレート側の変数名の後に | を付け、さらに修飾子と呼ばれる命令を追加しています。nl2br は改行を改行タグに変換する修飾子です。また、

<p>{$test|escape}</p>

のように escape 修飾子を指定すると、HTMLを無効にすることができます。修飾子を複数指定したい場合、

<p>{$test|escape|nl2br}</p>

と指定することができます。このように指定すると、先頭の修飾子から順に実行されていきます。また、

<p>{$test|default:'値はありません。'}</p>

このように default という修飾子を指定すると、$test に何も値が割り当てられていない場合に 値はありません。 と表示させることができます。: に続いて、任意の文字列を指定することができます。

Smartyには、他にも色々な修飾子が実装されています。

すべての変数に修飾子を適用

修飾子を利用したければ、変数に対してその都度修飾子を指定します。ですが escape などは不正な投稿を防ぐためにも、常に設定しておきたいです。
修飾子を毎回指定しても問題ないのですが、それでは少し面倒です。うっかり指定を忘れてしまう可能性もあります。

このような対策に、すべての変数に対して指定した修飾子を、常に適用させることができます。具体的には default_modifiers というプロパティを使用します。

<?php

require_once 'smarty/Smarty.class.php';

$smarty = new Smarty();
$smarty->template_dir = 'templates/';
$smarty->compile_dir  = 'templates_c/';

$smarty->default_modifiers = array('escape');

$smarty->assign('test', "テスト。\nこれは<em>テスト</em>です。");

$smarty->display('test.html');

?>

このように default_modifiers に対して、配列の形式で修飾子を設定することができます。上の場合、Smartyにセットした値すべてに escape 修飾子が適用されます。

また、修飾子はいくつでも指定することができます。以下は escapenl2br を指定した例です。

$smarty->default_modifiers = array('escape', 'nl2br');

もし部分的に default_modifiers の指定を無効にしたければ、nofilter を指定します。具体的には

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>
<body>
<p>{$test nofilter}</p>
</body>
</html>

このように指定すれば、$test には default_modifiers の指定が適用されません。

他のテンプレートを読み込む

include を使用すると、現在のテンプレートに他のテンプレートを読み込むことができます。例えば header.html というテンプレートを作成し、以下の内容を述しておきます。

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>サンプル</title>
</head>

このテンプレートを読み込むには、以下のようにします。

<html>
{include file='header.html'}
<body>
<p>{$test}</p>
</body>
</html>

このようなテンプレートを作成すると、{include file='header.html'} の部分が header.html の内容に置き換わります。

現在のテンプレートで利用可能なすべての変数は、読み込まれたテンプレートでも利用することができます。これを利用すれば、全ページで共通のヘッダ部分を1つのファイルにまとめたりすることができます。

上手く利用すれば、テンプレートの修正を効率よく行うことができます。