なぜテンプレートを使うのか
PHP でテンプレートシステムを使うべき理由は?
PHP 自体がテンプレート言語なのに、なぜ PHP でテンプレートシステムを使うのでしょうか。
まずは、興味深い紆余曲折に満ちたこの言語の歴史を簡単に振り返ってみましょう。HTML ページの生成に使われた最初期のプログラミング言語のひとつは C でした。しかし、この用途に C を使うのは実用的でないことがすぐに明らかになります。そこで Rasmus Lerdorf は PHP を作り、バックエンドの C とともに動的な HTML を生成しやすくしました。PHP はもともとテンプレート言語として設計されましたが、時とともに機能が追加され、本格的なプログラミング言語になっていきました。
とはいえ、今もテンプレート言語として機能します。PHP ファイルには HTML
ページを書くことができ、その中で変数を <?= $foo ?> のように出力できます。
PHP の歴史の初期には、表示(HTML/CSS)とアプリケーションロジックを厳格に分離する目的で、Smarty というテンプレートシステムが生まれました。Smarty は意図的に PHP よりも制限された言語を提供し、たとえば開発者がテンプレートからデータベースへ問い合わせることができないようにしました。その一方で、プロジェクトに依存関係を追加し、複雑さを増し、プログラマーに新しい Smarty 言語の習得を強いました。その利点には議論の余地があり、テンプレートには引き続き素の PHP が使われ続けました。
やがてテンプレートシステムは有用なものになっていきます。継承やサンドボックスモードといった概念、そして純粋な PHP と比べてテンプレート作成を大きく簡単にする多くの機能が導入されました。セキュリティというテーマ、XSS のような脆弱性の存在、そしてエスケープの必要性が前面に出てきます。テンプレートシステムは、プログラマーがエスケープを忘れて深刻なセキュリティホールを作ってしまうリスクをなくすために、自動エスケープを導入しました(これにも落とし穴があることは、すぐあとで見ていきます)。
今日では、テンプレートシステムの利点は導入にかかるコストを大きく上回ります。ですから、使う意味は十分にあります。
なぜ Latte は Twig や Blade より優れているのか?
理由はいくつかあります。快適さに関わるものもあれば、本質的に役立つものもあります。Latte はその両方を兼ね備えています。
まずは快適さの話から。 Latte は PHP
と同じ構文を持っています。違いはタグの書き方だけで、<?= や ?>
の代わりに短い { と }
を好んで使います。つまり、新しい言語を覚える必要がありません。習得コストは最小限です。そして何より、開発中に
PHP
言語とテンプレート言語のあいだを絶えず「切り替える」必要がありません。どちらも同じものだからです。Python
風の構文を使う Twig のテンプレートでは、プログラマーは 2
つの異なる言語を行き来しなければなりません。
次に、きわめて実用的な理由。 Twig、Blade、Smarty
といったテンプレートシステムはどれも、自動エスケープという形で
XSS への保護を備えるように進化してきました。より正確に言えば、htmlspecialchars()
関数を自動的に呼ぶということです。しかし Latte
の作者は、それがそもそも正しい解決策ではないことに気づきました。というのも、ドキュメントの場所ごとに必要なエスケープ方法が異なるからです。素朴な自動エスケープは、誤った安心感を生むという意味で危険な機能なのです。
自動エスケープが機能し、信頼できるものであるためには、データがドキュメントのどこに出力されるのか(これをコンテキストと呼びます)を認識し、それに応じてエスケープ関数を選ばなければなりません。つまりコンテキストに応じたものでなければなりません。そして Latte はそれができます。Latte は HTML を理解します。テンプレートを単なる文字の並びとしてではなく、何がタグで何が属性なのかを理解したうえで扱います。だからこそ、HTML テキストの中、HTML タグの中、JavaScript の中で、それぞれ異なるエスケープを行うのです。
Latte はコンテキストに応じたエスケープを備えた最初にして唯一の PHP テンプレートシステムです。つまり、本当に安全な唯一のテンプレートシステムです。
もうひとつ快適な理由。 Latte は HTML を理解するので、ほかにも非常に快適な機能を提供できます。たとえば n:属性。あるいはリンクをチェックする機能。まだまだあります。
エスケープとは何か?
エスケープとは、ある文字列を別の文字列に挿入する際に、望ましくない影響やエラーを防ぐため、特別な意味を持つ文字を対応する並びに置き換える処理のことです。たとえば
HTML テキストに文字列を挿入する場合、<
という文字は特別な意味(タグの開始)を持つので、対応する並び、すなわち HTML エンティティ
< に置き換えます。これによってブラウザは <
という記号を正しく表示できます。
PHP のコードを書くときのエスケープの簡単な例としては、文字列の中に引用符を入れるためにバックスラッシュを前に付けることが挙げられます。
エスケープについては XSS からどう身を守るかの章でさらに詳しく扱います。
Latte のテンプレートからデータベースクエリを実行できるか?
テンプレートの中では、プログラマーが渡したオブジェクトを扱えます。プログラマーがそう望むなら、データベースのオブジェクトをテンプレートに渡して、そこでクエリを実行させることもできます。それが意図した動作なら、妨げる理由はありません。
事情が変わるのは、クライアントや外部のコーダーにテンプレートを編集させたい場合です。その場合、データベースへのアクセスは絶対に持たせたくありません。もちろんデータベースのオブジェクトをテンプレートに渡したりはしませんが、別のオブジェクト経由でたどり着けてしまったらどうでしょう。その答えがサンドボックスモードです。テンプレートの中でどのメソッドを呼べるかを定義できるので、セキュリティ侵害を心配する必要がなくなります。
Latte、Twig、Blade のようなテンプレートシステムの主な違いは?
Latte、Twig、Blade といったテンプレートシステムの違いは、主に構文、セキュリティ、フレームワークとの統合にあります。
- Latte: PHP の構文を使うので、習得も利用も簡単です。コンテキストに応じたエスケープにより、XSS 攻撃に対する最高水準の保護を提供します。Nette Framework とよく統合されていますが、単体でも使えます。
- Twig: Python 風の構文を使い、PHP
とは大きく異なります。コンテキストを区別せずにエスケープします(単純な
htmlspecialchars)。Symfony フレームワークとよく統合されています。 - Blade: PHP
と独自構文の混合を使います。コンテキストを区別せずにエスケープします(単純な
htmlspecialchars)。Laravel の機能やエコシステムと密に統合されています。
企業にとってテンプレートシステムを使う価値はあるか?
まず、習得・利用にかかるコストと全体の利点は、システムによって大きく異なります。Latte は PHP の構文を使うため、この言語をすでに知っているプログラマーにとって学習が非常に簡単です。たいていは数時間で Latte を十分に扱えるようになるので、教育コストが下がり、技術の導入が早まり、そして何より日々の利用効率が上がります。
さらに Latte は、独自のコンテキストに応じたエスケープ技術によって、XSS 脆弱性に対する高い保護を提供します。この保護はウェブアプリケーションの安全性を確保し、ユーザーや企業のデータを危険にさらす攻撃のリスクを最小化するうえで決定的です。ウェブアプリケーションのセキュリティは、企業の評判を守るうえでも重要です。セキュリティ上の問題は顧客の信頼の喪失につながり、市場における企業のイメージを損ないかねません。
Latte を使うことは、開発と保守の両方を容易にし、全体のコストも下げます。ですからテンプレートシステムを使う価値は間違いなくあります。
Latte はウェブアプリケーションのパフォーマンスに影響するか?
Latte のテンプレートは高速に処理されますが、本番環境ではこの点は実質的に問題になりません。というのも、テンプレートファイルが解析されるのは最初に表示されたときの一度きりだからです。その後はネイティブの PHP コードにコンパイルされてディスクに保存され、以降のリクエストでは再コンパイルなしで実行されます。
これが本番環境での動作です。開発中は、内容が変わるたびに Latte のテンプレートが再コンパイルされるので、開発者は常に最新版を目にすることになります。