ITOO's Blog

プログラミングを語る

素のPHPでテンプレートエンジンを作った

はじめに

手軽に使えるテンプレートエンジンを作りました。ディレクトリ構成はこんな感じ

app
├── sample.php
├── templates
│   └── index.php
└── utils
    └── Template.php

テンプレートエンジン

<?php

class Template
{
    const DEFAULT_TPL_PATH = __DIR__ . '/../templates';

    public $tpl_path;

    public function __construct()
    {
        $this->tpl_path = self::DEFAULT_TPL_PATH;
    }

    /**
     * @param string $path
     */
    public function setTemplatePath($path)
    {
        $this->tpl_path = rtrim($path, '/');
    }

    private function escapeArrayRec(&$attr_dict)
    {
        foreach ($attr_dict as $key => $val) {
            if (is_array($val)) {
                $attr_dict[$key] = $this->escapeArrayRec($val);
            } else {
                $attr_dict[$key] = htmlspecialchars($val, ENT_QUOTES, 'UTF-8');
            }
        }
        return $attr_dict;
    }

    /**
     * @param string $tpl_file
     * @param array $attr_dict
     */
    public function render($tpl_file, $attr_dict = [], $escape = true)
    {
        if ($escape) {
            $this->escapeArrayRec($attr_dict);
        }

        extract($attr_dict);

        include($this->tpl_path . $tpl_file);
    }
}

最低限の機能しかありませんが、簡単なアプリでビューと処理を分けたいときは重宝するのではないでしょうか。 エスケープを行ってるので、Javascriptが埋め込まれても実行されません。

index.php

テンプレートファイル

<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<h1><?= $name ?>さん</h1>
<h2>趣味</h2>
<ul>
    <?php foreach ($favorites as $favorite): ?>
        <li><?= $favorite ?></li>
    <?php endforeach; ?>
</ul>
</body>
</html>

sample.php

実際に表示を行うファイル

<?php

require_once __DIR__ . "/utils/Template.php";


$tpl = new Template();
$name = 'hogehoge';
$favorites = ['音楽', 'サッカー', '', '家電'];
$tpl->render('/index.php', compact('name', 'favorites'));

app/配下でphp -S localhost:80とコマンドを打ってから、ブラウザでlocalhost:80/sample.phpと実行してみてください。 値が埋め込まれてindex.phpが表示されたら成功です。

まとめ

PHPの機能を使っただけの簡単なテンプレートエンジンですが、ショートタグなども駆使すれば使えば結構使い勝手は良いのではないでしょうか。 さすがHypertext Preprocessorです。PHPの学習などにもお役に立てたら幸いです。

最後に

次は、このテンプレートエンジンを生かしてもう少しMVCモデルっぽくしてみたいと思います。お楽しみに。 「こんな風にしたらもっとよくなるよ」「ここ間違ってるよ」などなど意見、質問、アドバイスをいただけたら嬉しいです。

参考資料