第12回 Smartyとフレームワーク(その2:Zend Framework編) (その1)

前回に引き続き、SmartyをPHPのフレームワーク上で使うための方法について説明したいと思います。今回はZend Frameworkです。
Zend Frameworkとは
Zend FrameworkはZend Technologies社が開発したオープンソースのフレームワークです。
Zend Technologies社といえば、PHP5の実行エンジンであるZend Engine2.0を開発した会社としても知られていますね。
Zend Frameworkの大きな特徴は、完全なオブジェクト指向で書かれていることです。そのため各コンポーネントが「疎結合」で結びついており、完全に独立して使うことができます。例えばControllerクラスは必要ないけどDBのクラスは使いたい、などといった利用も可能になっています。
同様にビュークラスも独立性が高く、また拡張も容易に可能な作りになっています。
Zend FrameworkのオフィシャルのドキュメントにSmartyをテンプレートエンジンで使う方法が例として書かれていることからもわかるように、Smartyとの相性がいいPHPフレームワークといえるでしょう。(*1)
前準備
ではZend FrameworkでSmartyを使うための準備を進めたいと思います。ここでは既にZend Frameworkのインストールや設定が完了してると仮定して話を進めます。
Zend Frameworkのインストール方法や設定に関しての説明は省略しますので、詳細はZend Frameworkのマニュアルなどを参考にしてください。
各ファイルを配置するディレクトリ構成ですが、ここでは以下のような構成で作成します。
/var/www/zend_smarty/ ├application/ │ ├ controllers/ │ └ smarty/ │ ├ cache/ │ ├ configs/ │ ├ templates/ │ └ templates_c/ ├ library/ └ public/
publicディレクトリがドキュメントルートになります。ApacheなどのWebサーバーで設定してください。
そしてapplicationディレクトリ以下にコントローラやSmartyテンプレートなどを配置していきます。
本来であれば、データベースなどを扱うモデルクラスを置くためのmodelsディレクトリなども必要ですが、今回は省略します。
smartyディレクトリの下のcacheディレクトリ、templates_cディレクトリはWebサーバーが書き込みできるよう権限を修正してください。
そしてlibraryディレクトリは、SmartyとZend Frameworkをつなぐためのラッパークラスを配置します。
ビューをSmartyに置き換える

さてZend FrameworkではZend_Viewというビュークラスが標準で用意されています。コントローラからパラメータを受け取って、「ビュースクリプト」の内容を表示します。
しかし、このクラスは必要最低限のユーティリティ関数が用意されているだけで、テンプレートエンジンは用意されていません。標準のビュースクリプトも、PHPのコードを書いてビューを生成するだけの機能になっています。
そこで、テンプレートエンジンとしてSmartyを用いることができるようにするために、Zend_Viewを置き換えるためのビュークラスを作成します。
Zend FrameworkにはZend_View_Interfaceというオブジェクトインターフェースが用意されています。
このZend_View_Interfaceインターフェースは、Zend_Viewを置き換えるためのビュークラスを作成するのに必要なインターフェースで、ここで宣言されているメソッドを実装することによって、Zend_View互換のビュークラスを作成することができます。
Zend_View_Interfaceで宣言されているメソッドは以下の通りです。
| getEngine() | テンプレートエンジンオブジェクトを返す |
| setScriptPath($path) | ビュースクリプト/テンプレートへのパスを設定 |
| setBasePath($path, $prefix = 'Zend_View') | すべてのビューリソースへのベースパスを設定 |
| addBasePath($path, $prefix = 'Zend_View') | ビューリソースへのベースパスを追加 |
| getScriptPaths() | 現在のスクリプトのパスを取得 |
| assign($spec, $value = null) | テンプレート変数を手動で代入したり、複数の変数を一括設定したりする |
| clearVars() | 代入済みのテンプレート変数を削除 |
| render($name) | 指定したテンプレートをレンダリング |
| テンプレート変数をオブジェクトのプロパティとして代入するためのオーバーロードメソッド |
| __set($key, $value) |
| __isset($key) |
| __unset($key) |
では、Zend_View_Interfaceのメソッドを実装したSmartyのラッパークラスを作成します。
Zend Frameworkのリファレンスマニュアルで例としてあげられているラッパークラスの転載なので、こちらも参照してください。
1 <?php
2 class Zend_View_Smarty implements Zend_View_Interface
3 {
4 /**
5 * Smarty object
6 * @var Smarty
7 */
8 protected $_smarty;
9
10 /**
11
* コンストラクタ
12 *
13 * @param string $tmplPath
14 * @param array $extraParams
15 * @return void
16 */
17 public function __construct($tmplPath = null, $extraParams = array())
18 {
19 $this->_smarty = new Smarty;
20
21 if (null !== $tmplPath) {
22 $this->setScriptPath($tmplPath);
23 }
24
25 foreach ($extraParams as $key => $value) {
26 $this->_smarty->$key = $value;
27 }
28 }
29
30 /**
31
* テンプレートエンジンオブジェクトを返します
32 *
33 * @return Smarty
34 */
35 public function getEngine()
36 {
37 return $this->_smarty;
38 }
39
40 /**
41
* テンプレートへのパスを設定します
42 *
43
* @param string $path パスとして設定するディレクトリ
44 * @return void
45 */
46 public function setScriptPath($path)
47 {
48 if (is_readable($path)) {
49 $this->_smarty->template_dir = $path;
50 return;
51 }
52
53 throw new Exception('無効なパスが指定されました');
54 }
55
56 /**
57
* 現在のテンプレートディレクトリを取得します
58 *
59 * @return string
60 */
61 public function getScriptPaths()
62 {
63 return array($this->_smarty->template_dir);
64 }
65
66 /**
67
* setScriptPath へのエイリアス
68 *
69 * @param string $path
70 * @param string $prefix Unused
71 * @return void
72 */
73 public function setBasePath($path, $prefix = 'Zend_View')
74 {
75 return $this->setScriptPath($path);
76 }
77
78 /**
79
* setScriptPath へのエイリアス
80 *
81 * @param string $path
82 * @param string $prefix Unused
83 * @return void
84 */
85 public function addBasePath($path, $prefix = 'Zend_View')
86 {
87 return $this->setScriptPath($path);
88 }
89
90 /**
91
* 変数をテンプレートに代入します
92 *
93
* @param string $key 変数名
94
* @param mixed $val 変数の値
95 * @return void
96 */
97 public function __set($key, $val)
98 {
99 $this->_smarty->assign($key, $val);
100 }
101
102 /**
103
* empty() や isset() のテストが動作するようにします
104 *
105 * @param string $key
106 * @return boolean
107 */
108 public function __isset($key)
109 {
110 return (null !== $this->_smarty->get_template_vars($key));
111 }
112
113 /**
114 * オブジェクトのプロパティに対して unset() が動作するようにします
115 *
116 * @param string $key
117 * @return void
118 */
119 public function __unset($key)
120 {
121 $this->_smarty->clear_assign($key);
122 }
123
124 /**
125 * 変数をテンプレートに代入します
126 *
127 * 指定したキーを指定した値に設定します。あるいは、
128 * キー => 値 形式の配列で一括設定します
129 *
130 * @see __set()
131
* @param string|array $spec 使用する代入方式 (キー、あるいは キー => 値 の配列)
132
* @param mixed $value (オプション) 名前を指定して代入する場合は、ここで値を指定します
133 * @return void
134 */
135 public function assign($spec, $value = null)
136 {
137 if (is_array($spec)) {
138 $this->_smarty->assign($spec);
139 return;
140 }
141
142 $this->_smarty->assign($spec, $value);
143 }
144
145 /**
146
* 代入済みのすべての変数を削除します
147 *
148 * Zend_View に {@link assign()} やプロパティ
149 * ({@link __get()}/{@link __set()}) で代入された変数をすべて削除します
150 *
151 * @return void
152 */
153 public function clearVars()
154 {
155 $this->_smarty->clear_all_assign();
156 }
157
158 /**
159 * テンプレートを処理し、結果を出力します
160 *
161 * @param string $name 処理するテンプレート
162
* @return string 出力結果
163 */
164 public function render($name)
165 {
166 return $this->_smarty->fetch($name);
167 }
168 }
ポイントは、Smartyクラスのインスタンスをラッパークラスのメンバ変数として保持している点です。
そしてインターフェースのメソッドを通して、Smartyクラスのメソッドを呼び出すことでZend Frameworkの枠組みでも違和感なくSmartyを使うことが出来るというわけです。
例えばSmartyクラスのメソッドassign()ですが、Zend_View_Interfaceにもassign()メソッドはありますので、それをラッパーとして使うことも可能です。
また、Zend_Viewでは直接メンバ変数にパラメータを渡すことで、それをテンプレートでも使うことができますが、それを実現するために__set()メソッドもSmartyのassign()メソッドのラッパーとして実装することでZend_Viewと同様の感覚でSmartyテンプレートを使えるようになります。
----
(*1) Zend Framework公式サイト
http://framework.zend.com/manual/en/zend.view.scripts.html
http://framework.zend.com/manual/ja/zend.view.scripts.html (日本語訳)







