アシアル株式会社
田中正裕 <masahiro@asial.co.jp>
Smartyの導入と活用
アシアル株式会社 田中正裕
テンプレートエンジンの必要性
以下のような問題で衝突していた
①
一旦プログラムコードを埋め込んでしまうと、デザイナーがHTML
を修正できなくなる
②
プログラマーとデザイナーが同時に1つのファイルを修正して、衝
突してします
③
デザインの見栄えを修正したくても、プログラマーにお願いしない
といけない
昔(2000年ごろ?)の典型的なPHPのコード:
<?php // ・・・処理 ?> <html> <body> <?php print("Hello World!"); ?> </body> </html>アシアル株式会社 田中正裕 http://www.asial.co.jp/
PHPをテンプレートエンジンにする
古典的ですが、今でもよく用いられます。デザインとプログラム
の分離は出来ていますし、速度も速いというメリットがあります。
ただし、テンプレートエンジンと呼べるかは微妙です。
<?php //プログラムコード require("hoge_template.php"); ?> <?php // テンプレートコード ?> <html> <body> <?=$var?> </body> </html> hoge.php hoge_template.phpアシアル株式会社 田中正裕
PHPをテンプレートとして使うために
変数を表示する
• <?=$var?>if構文の別の書き方
• <? if($aaa) ?> true時の処理 <? else; ?> その他の処理 <? endif; ?>for構文の別の書き方
• <? for ($i = 0; $i < 10; $i++): ?> これは<?=$i?>番目の処理です
<? endfor; ?>
foreach構文の別の書き方
• <? foreach ($array as $key => $value): ?> キー:<?=$key?> 値:<?=$value?>
<? endforeach; ?>
アシアル株式会社 田中正裕
テンプレートエンジンが生まれた背景
l
デザイナーにとって、コードが読みづらい
l
ショートタグを使うのは、望ましくない
l
文書をフォーマットする、という意味では使
いづらい。
それでも・・・
もう少し「テンプレートを読み込んで処理
する」ことに主眼をおいたライブラリがあ
ると良いのでは?
アシアル株式会社 田中正裕
テンプレートエンジン登場
そこで、テンプレートエンジンを使うと、以下のよ
うなコードに変わります(Smartyの例)。
<?php require("common.php"); require("/path/to/libs/Smarty.class.php"); $smarty = new Smarty();$smarty->assign("var1", "Hello World"); $smarty->display("hoge.html"); ?> スクリプト側(hoge.php) <html> <body> {$var1} </body> </html> テンプレート側(hoge.html)
アシアル株式会社 田中正裕
テンプレートを使った場合の作業フロー
開発時
修正時
デザイン作成 タグ打ち テンプレート 埋め込み ロジック作成 テンプレート 修正 ロジック修正 修正依頼 デザイナー プログラマー デザイナー プログラマー 完了 完成 共同作業アシアル株式会社 田中正裕
なぜSmarty?
①
Smartyを使った事例が多い(一番メジャー、
開発歴も長い)
②
そこそこ良くできている(ただしハマる所は
知っておく必要あり)
③
日本語のドキュメントが多い(日本語マニュ
アル、書籍も出ている)
同じような動作をするテンプレートエンジンは数
多くありますが、今回はSmartyに焦点を当てます。
アシアル株式会社 田中正裕
テンプレートエンジンを使うメリット
u
ビューを分離できる
u
HTML、コードとも見やすくなる(はず)
アシアル株式会社 田中正裕
使わないメリット
u
やっぱり遅くなる
u
最初のセットアップが大変
アシアル株式会社 田中正裕
特徴的な機能
u
関数
u
修飾子
u
キャッシュ
u
ブロック
u
カスタマイズ
u
コンパイルキャッシュ
等々
単にビューを分離するだけではなく、いろいろな
機能を持っています。
アシアル株式会社 田中正裕
Smartyの動作の仕組み
初回読み込み時
PHPファイル内
テンプレート ファイル 読み込みパース
コンパイル
出力
コンパイルキャッシュ
ファイル
保存次回以降
PHPファイル内
出力
読み込みアシアル株式会社 田中正裕
Smartyのセットアップ
1.
Smarty本体をダウンロード(http://smarty.php.net)
2.
ディレクトリに展開
3.
templatesディレクトリ、templates̲cディレクトリを作成(デ
フォルトはスクリプトと同階層)
4.
templates̲cディレクトリに、Apacheから書き込める権限を付与
5.
require ("/path/to/lib/Smarty.class.php");
6.
$smarty = new Smarty(); でSmartyオブジェクトを作成。
<?php
require("/path/to/libs/Smarty.class.php"); $smarty = new Smarty();
$smarty->assign("var1", "Hello World"); $smarty->display("hoge.html");
?>
アシアル株式会社 田中正裕
Smartyの使い方
<?php
$scalar = "Hello World";
$array = array ("a" => "A", "b" => "B"); require("libs/Smarty.class.php");
$smarty = new Smarty();
$smarty->assign("scalar", $scalar); $smarty->assign("array", $array); $smarty->display("hoge.html"); ?>
PHP側(hoge.php)
変数を表示する場合:{$scalar} 配列を表示する場合:{$array.a}、{$array.b}テンプレート側(templates/hoge.html)
① インスタンス 作成 ② 変数のアサイ ン ③ 出力 or 取得アシアル株式会社 田中正裕
Smartyの設定
// デバッグコンソールを出す({debug}関数でも可能) $smarty->debugging = true; // 各必須ディレクトリの場所の変更 $smarty->template_dir = "/path/to/template_dir"; $smarty->compile_dir = "/path/to/compile_dir"; // デリミタの変更 $smarty->left_delimiter = "{{"; $smarty->right_delimiter = "}}"; // コンパイルを強制する $smarty->force_compile = true;設定の例:
$smartyオブジェクトのプロパティを修正して、各種設定
ができる
アシアル株式会社 田中正裕
Smarty関数の使い方
{include file="ファイル名"}他のファイルを読み込む場合:
PHPの関数とは別に、Smarty上で関数が利用できる。これ
により、ビュー特有の処理を関数でまとめることができる。
{foreach from=$array key=key item=item} キー:{$key} 値:{$item}
{/foreach}
foreachを使う場合:
そのほかにも、いくつかの関数がデフォルトで用意されている。
また、自作で関数を作ることも可能。
アシアル株式会社 田中正裕
Smarty修飾子(modifier)の使い方
{$value|number_format}数値をフォーマットする場合:
関数をより簡単にした形。Linuxでいうパイプの役割をして、
表現するデータに合わせて表示形式を変更できる。
{$value|escape}HTMLエスケープを行う場合(XSS対策):
{$value|escape|nl2br}また修飾子は重ねることが可能:
{$value|strip_tags|substr:3}引数を渡すことも可能:
アシアル株式会社 田中正裕
自作関数の利用
関数・修飾子はカスタムで作ることができます。作り方には
2通りあります。プラグインに保存する場合:
<?php
function smarty_function_imagetag ($params, &$smarty) { $filename = $params["filename"];
list($width, $height, $type, $attr) = getImageSize($filename); return "<img src=¥"$filename¥" $attr />";
} ?>
② smarty̲function̲関数名とした関数作成し、smarty.function.
関数名という名称でプラグイン用ディレクトリに保存する
$smarty->plugins_dir = array("plugins", "my_plugins");
① プラグイン用ディレクトリを作成し、そのディレクトリを
plugins̲dirとして指定する
{imagetag filename="image.png"}
③ 関数を使う
アシアル株式会社 田中正裕 http://www.asial.co.jp/
キャッシュ
$smarty->caching = true;□ キャッシュ機能を有効にする
初回読み込み時
PHPファイル内
テンプレート ファイル 読み込み出力
キャッシュ
保存次回以降
PHPファイル内
出力
読み込みアシアル株式会社 田中正裕
Tips
① クロスサイトスクリプティング脆弱性を強化する
class MySmarty extends Smarty {
function assign($varname, $value) {
$parent->assign($varname, htmlspecialchars($value, ENT_QUOTES)); }
}
$smarty = new MySmarty();
assignメソッドを改良し、デフォルトでHTMLエスケープされた状
態でassignする
② テンプレート変数を連想配列で1つにまとめる
assignメソッドを必要回数分記述するよりは、$template̲var等
の変数に連想配列形式でテンプレート変数を割り当てると便利。
$template_var["var1"] = "Hello World";$template_var["var2"] = "hogehoge"; $smarty->assign($template_var);
アシアル株式会社 田中正裕
SmartyDWT
DreamweaverからSmartyを簡単に操作する
ためのプラグイン。
アシアル株式会社 田中正裕
Template Lite
(http://templatelite.sourceforge.net/)
以前Smarty Lightと呼ばれていたテンプレー
トエンジンを引き継ぐ形で、別の作者によって
公開されているもの。
Smartyとほぼ同等の機能を備えている上、for
やswitch関数などが追加されている。
アシアル株式会社 田中正裕
Simplate
(http://simplate.aimy.jp/)
Smartyの機能をPHPエクステンションの形で
実現したもの。必要最低限の機能しか有してい
ないが、とても高速に動作する。
Smarty Simplate 変数のアサイン ○ ○ デリミタの変更 ○ ○関数 {function var=val}形式 {関数名($var)}形式
修飾子 ○ ×
ループ処理 section,foreach section,foreach
キャッシュ ◎(キャッシュID対応) △(出力の保存のみ)
アシアル株式会社 田中正裕 http://www.asial.co.jp/
ベンチマーク対決
Smarty、Simplate、TemplateLiteで、どの程度
速度が異なるのか?PHP 5.1.4で計測。
<?php$scalar = "Hello World";
$array = array ("a" => "A", "b" => "B", "c" => "C"); $smarty->assign("scalar", $scalar); $smarty->assign("array", $array); $smarty->display("hoge.html"); ?>
PHP側(hoge.php)
スカラー値:{$scalar}<br> 配列:{$array.a}、{$array.b}、{$array.c} <ul>{foreach from=$array item=a key=k} <li>キー:{$k} 値:{$a}</li>
{/foreach} </ul>
アシアル株式会社 田中正裕
計測結果
圧倒的にSimplateが高速。これは、SimplateがPHPエクス
テンションとして動作するため、処理速度が速く、また機能
実装もシンプルであることが大きな要因だと思います。
ab n 1000 c 10 or 20 http://url・・・アシアル株式会社 田中正裕