Twig と Smarty、PHPテンプレートエンジンの選び方を考える

概要

PHP でビューを組み立てるとき、生の PHP を埋め込む方式のほかに、専用のテンプレートエンジンを使う選択肢があります。代表的なのが Twig と Smarty です。どちらも「ロジックとビューを分離する」という同じ目的を持ちながら、設計思想・記法・実行モデルにはっきりした違いがあります。

この記事では、公開情報に基づいて両者の特徴を整理し、「新規なら Twig、既存資産があるなら Smarty」という結論に至るまでの判断軸を考察します。

なぜテンプレートエンジンを使うのか

生 PHP でもビューは書けますが、専用エンジンを挟む理由は主に3つあります。

  1. ロジックとビューの分離 — テンプレート内でできることを制限し、責務を明確にする
  2. 安全な出力 — 自動エスケープなどで XSS を防ぎやすくする
  3. 再利用性 — 継承・インクルード・ブロックでレイアウトを共通化する

Twig と Smarty はどちらもこの目的を満たしますが、力点が違います。

設計思想の違い

Twig : 安全なデフォルトと制限された表現力

  • 出力の自動エスケープがデフォルトで有効
  • テンプレート内のロジックを意図的に制限し、ロジックの混入を防ぐ
  • サンドボックス機能でユーザー提供テンプレートを安全に実行できる
  • Symfony の標準テンプレートエンジンであり、単体でも利用可能

Smarty : 柔軟さと歴史ある資産

  • 長い歴史と豊富な採用実績(特にレガシー PHP プロジェクト)
  • 成熟したプラグイン機構で独自の修飾子・関数を追加しやすい
  • 組み込みの出力キャッシュ機構
  • {$var} 系の、PHP 経験者に馴染みやすい記法

記法の比較

変数出力とエスケープ

{# Twig: デフォルトで自動エスケープされる #}
<p>{{ user.name }}</p>
<p>{{ content|raw }}</p>  {# 明示的にエスケープを外す #}
<p>{{ title|upper|trim }}</p>  {# フィルタのチェーン #}
{* Smarty: 修飾子で明示するのが基本 *}
<p>{$user.name|escape}</p>
<p>{$title|upper|trim}</p>

ここで重要なのがエスケープの扱いです。Twig は「デフォルトで安全、必要なときだけ外す」。Smarty は「必要な箇所で明示的にエスケープする」(設定で有効化することも可能)。XSS 対策の初期安全度では Twig に分があります。

制御構文

{% for item in items %}
  <li>{{ item.label }}</li>
{% else %}
  <li>データがありません</li>
{% endfor %}
{foreach $items as $item}
  <li>{$item.label}</li>
{foreachelse}
  <li>データがありません</li>
{/foreach}

テンプレート継承

{# base.html.twig #}
<html>
  <body>{% block content %}{% endblock %}</body>
</html>

{# page.html.twig #}
{% extends "base.html.twig" %}
{% block content %}<h1>ページ内容</h1>{% endblock %}

Smarty も 3.x 以降で {extends} / {block} による継承に対応しています。

拡張性の比較

Twig(Extension クラス):

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends AbstractExtension
{
    public function getFilters(): array
    {
        return [new TwigFilter('yen', fn(int $v) => '¥' . number_format($v))];
    }
}

Smarty(プラグイン登録):

$smarty->registerPlugin('modifier', 'yen', fn(int $v) => '¥' . number_format($v));

どちらも十分な拡張性を備えますが、Twig は Extension という体系と Symfony の DI との親和性が特徴です。

パフォーマンスとキャッシュ

両者ともテンプレートを PHP コードにコンパイルしてキャッシュする方式です。初回のコンパイルコストはありますが、2回目以降はコンパイル済みの PHP が使われるため実行時オーバーヘッドは小さくなります。Smarty は加えて「出力キャッシュ」を組み込みで持ち、レンダリング結果自体をキャッシュできます。

開発時はキャッシュにハマりやすいので、次を押さえておきましょう。

  • Twig: cache => false または auto_reload => true
  • Smarty: $smarty->setCaching(false) / コンパイルは変更検知で再生成

選定の判断軸

観点 Twig Smarty
自動エスケープ デフォルト有効 明示 or 設定で有効化
フレームワーク Symfony 標準 特定FW非依存・レガシー実績
記法 独自({% %} / {{ }}) PHP 寄り({$var})
学習コスト Symfony 経験者は低い PHP 経験者は低い
既存資産の活用 移行コスト大 既存 tpl をそのまま活かせる
セキュリティ初期値 高い 運用でカバーが必要

注意点

  • 既存プロジェクトへの後付け: すでに Smarty で大量のテンプレート資産があるなら、Twig への全面移行は記法変換・検証コストが高くつきます。段階移行が現実的です。
  • セキュリティのデフォルト差: Smarty ではエスケープを書き忘れない運用が必要です。テンプレートレビューやリンタで担保する仕組みを併用すると安全です。
  • バージョン差: Smarty は 5.x で名前空間対応など近代化が進んでいます。採用バージョンのドキュメントを必ず確認してください。

まとめ

  • 新規・Symfony 系・安全なデフォルトを重視 → Twig
  • 既存の Smarty 資産がある・PHP に近い書き味・移行コスト回避 → Smarty

技術選定は「どちらが優れているか」ではなく「今の制約に合うか」で決めるのが定石です。自動エスケープの初期安全度と Symfony エコシステムの後押しで、新規なら Twig を第一候補に。ただし既存資産を軽視した移行は割に合わないことが多く、そこは冷静に見極めたいところです。

\ 最新情報をチェック /

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。