プログラムの規模が大きくなってくると、ロジックとデザインを一緒にしていたのでは見通しの悪く分かり難いプログラムになってしまいます。
そこでMVCパターンを使用したロジックとデザインの分離が現場ではよく使われています。
PHPでも各種フレームワークの開発が盛んですが、今回はフレームワークと言うほど本格的ではなく気軽に使えて普遍性の高いSmartyを使ってみます。
まずはSmartyを解凍すると色々フォルダが出てきますが、必要なのはlibsフォルダだけです。
アップロードを行う場合、できるだけhtdocsより上のフォルダ、ブラウザからは見えないところに置きましょう。
レンタルサーバ等で権限がないなら仕方ありませんが、その場合は推測しにくいフォルダ名にした上で、.htaccessやダミーのindex.hrml等を設置して直接覗かれる可能性を減らしておきましょう。
一応言っておきますが、公開フォルダに置く=公開する、です。
今回はこのような形で設置しました。
homes
├htdocs
│ └(各phpファイル)
└smarty
├libsフォルダ
│ ├Smarty.php
│ └(各Smarty関連ファイル)
├templatesフォルダ
└templates_cフォルダ
smarty/libsはSmartyファイルを置く場所です。
smarty/templatesは、表示用のテンプレートファイルを置きます。
画面表示のデザインなどはテンプレートファイルで行い、ロジックはhtdocs以下のphpファイルで行うことで、ロジックとデザインを切り離すことができます。
smarty/templates_cはコンパイルされたファイルを置きます。
Smartyの特徴として、一度表示されたファイルをその状態で保存しておくことができます。
二度目以降のアクセス時にはそのファイルを表示することで、ロジックを経由する時間と負荷を軽減することができます。
コンパイルフォルダはPHPが書き込みを行いますので、所有者と権限を変更しておきましょう。
smarty/libs/Smarty.phpは下記スクリプトで、Smartyクラスをインスタンス化し、上記のテンプレートの位置を決める等の初期設定を行います。
別にsmarty/libs/Smarty.class.php等を直接変更してカスタマイズしてもいいのですが、その場合元に戻したりするのが面倒なので別ファイルで行います。
smarty/Smarty.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//定義
//Smartyの場所(SMARTY_DIRはSmarty内部でも使用)
define('SMARTY_DIR',dirname(__FILE__).'/');
//テンプレートファイル置き場
$smarty_templates_dir=SMARTY_DIR.'../templates/';
//コンパイル済ファイル置き場
$smarty_templates_c_dir=SMARTY_DIR.'../templates_c/';
//Smartyセット
require_once(SMARTY_DIR.'Smarty.class.php');
$smarty=new Smarty();
$smarty->template_dir = $smarty_templates_dir;
$smarty->compile_dir = $smarty_templates_c_dir;
|
このファイルをincludeすることで、$smartyでSmartyインスタンスにアクセスすることができるようになります。
簡単に使ってみましょう。
htdocs/index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//Smarty
require_once('./../smarty/libs/Smarty.php');
//変数
$str='string';
$arr=array(
'hoge'=>'<b>11111</b>'
,'hage'=>'<i>22222<i>'
);
//変数アサイン
$smarty->assign('a',$str);
$smarty->assign('b',$arr);
//表示
$smarty->display('index.html');
|
Smartyインスタンスにaとbふたつの変数をアサインし、index.htmlを表示せよ、と書かれています。
というわけで最後にindex.htmlを作ります。
smarty/templates/index.html
1
2
3
4
5
|
<html><body>
$str:{$a}<br />
$arr->hoge:{$b.hoge}<br />
$arr->hage:{$b.hage|escape}<br /></body></html>
|
これでどうなるかというと、
$arr->hoge:11111
$arr->hage:<i>22222<i>
</body></html>
このようなソースが出力されます。
Smartyテンプレート中で{$a}と書くと、その部分が$smarty->assignした変数の内容で置き換えられます。
同様に{$b.hoge}はアサインされた配列$b['hoge']が表示されます。
このように、テンプレート側では表示以外のことをさせないことで、表示のためにロジックをいじられたりすることを防ぐことができます。
またロジック側でも、表示側を考えることなく必要な変数をSmartyインスタンスに投げ込むだけでよくなります。
分業を行うことで、プログラムの見通しをよくすることができます。
またロジックを書くPG、テンプレートを書くコーダー等複数人が関わるプロジェクトに対し開発効率が上昇します。
逆に問題点としては、両者で変数の命名規則や配置方法などについてしっかり取り決めておかないと、あの変数は何処にあるんだ等行方不明になりやすくなったり、うまく表示するために奇怪なロジックを組んだりしなくてはならなくなったりします。