#テンプレートエンジンを作る
簡易的なテンプレートエンジンを作ってみたいと思います。
##テンプレートエンジンとは?
プログラムをビューとロジックに分けたときに、ビューの部分をマークアップエンジニアの人などがより分かりやすいような形で書くことを目的としています。
PHPで一番有名なテンプレートエンジンはSmartyだと思います。
今回はシンプルなものを紹介するため、このコードをそのまま利用することはお勧めしません。
##1.単純にHTMLファイルを別ファイルに分けたパターン
###プログラム
<?php
function view($template, Array $data = [])
{
extract($data);
require $template;
}
$data = [
'title' => 'テンプレートエンジン',
'author' => 'tak'
];
view('./view1.php', $data);
<h1><?=$title?></h1>
<p>この投稿は<?=$author?>によって書かれています。</p>
ビューファイル(view1.php)を外部ファイルに分けて、includeする方法です。
グローバル空間でincludeすると余計な変数も使用できる状態になってしまうため、関数内でincludeしています。
ビューの中で使う変数は連想配列で関数に渡し、extractで展開しています。
こうすることで、変数が増えても簡単にビューに渡すことができると思います。
###出力結果
<h1>テンプレートエンジン</h1>
<p>この投稿はtakによって書かれています。</p>
##2.変数を置き換えるパターン
###プログラム
<?php
function view($template, Array $data = [])
{
$source = file_get_contents($template);
echo preg_replace_callback('/\%(\w+)%/', function ($m) use ($data) {
if (!isset($data[$m[1]])) {
return '';
}
return $data[$m[1]];
}, $source);
}
$data = [
'title' => 'テンプレートエンジン2',
'author' => 'solder'
];
view('./view2.php', $data);
<h1>%title%</h1>
<p>この投稿は%author%によって書かれています。</p>
今度はview関数内でpreg_replace_callbackを使用しています。
こうすることで、テンプレートファイル内で%title%
⇒$title
の値に置換することができ、PHPコードの一切ないテンプレートファイルが作成できます。
これであれば、プログラムが分からないマークアップエンジニアの人でも簡単に編集できそうです。
ただし、この場合if文やループ処理が掛けません。
###出力結果
<h1>テンプレートエンジン2</h1>
<p>この投稿はsolderによって書かれています。</p>
##1と2を組み合わせた形
###プログラム
<?php
function view($template, Array $data = [])
{
$template = makeCache($template);
extract($data);
require $template;
}
function makeCache($template)
{
$cache = './cache/' . $template . '.tmp';
if(!is_file($cache)){
$source = file_get_contents($template);
$source = preg_replace_callback('/\%(\w+)%/', function ($m) {
return '<?=$' . $m[1] . '?>';
}, $source);
file_put_contents($cache, $source, LOCK_EX);
echo 'create cache!'.PHP_EOL;
}
return $cache;
}
$data = [
'title' => 'テンプレートエンジン3',
'author' => 'tak-solder'
];
view('./view3.php', $data);
<h1>%title%</h1>
<p>この投稿は%author%によって書かれています。</p>
テンプレートファイルは2と同じですが、表示のロジックが若干異なります。
今回は、2の状態からキャッシュとしてphpファイルを生成して、1の処理を当てはめています。
こうすることで、1,2の両方の技法を使うことができます。
中間のキャッシュファイルをファイルに書き出すため、2回目以降に実行するときはキャッシュファイルからそのまま1の処理を行うだけで、表示するHTMLを作成可能です。
処理速度向上や負荷軽減に役立ちます。
###キャッシュファイル
<h1><?=$title?></h1>
<p>この投稿は<?=$author?>によって書かれています。</p>
###出力結果
<h1>テンプレートエンジン3</h1>
<p>この投稿はtak-solderによって書かれています。</p>
ちょっとしたプログラムのためにいちいちsmartyを導入するのは大変!というときに参考にしてみてはいかがでしょうか。
あくまでも、参考程度にしてくださいね(^_^;