1 <?xml version="1.0" encoding="UTF-8"?>
3 <!-- EN-Revision: 17175 -->
4 <sect1 id="zend.controller.front">
5 <title>フロントコントローラ</title>
7 <sect2 id="zend.controller.front.overview">
11 <classname>Zend_Controller_Front</classname> は
12 <ulink url="http://en.wikipedia.org/wiki/Model-view-controller">Model-View-Controller
13 (MVC)</ulink> アプリケーションで用いられる
14 <ulink url="http://www.martinfowler.com/eaaCatalog/frontController.html">
15 フロントコントローラパターン</ulink> を実装したものです。
16 その役割は、リクエスト環境を初期化してリクエストの配送先を決定し、
17 見つかった配送先に処理を引き渡すことです。また、
18 レスポンスの内容を取得してそれをコール元に返します。
22 <classname>Zend_Controller_Front</classname> は <ulink
23 url="http://en.wikipedia.org/wiki/Singleton_pattern">シングルトンパターン</ulink>
24 も実装しています。つまり、どんな場合でもひとつのインスタンスしか存在しないことになります。
25 これを利用すると、コントローラをレジストリとして扱えるようになります。
29 <classname>Zend_Controller_Front</classname> は <link
30 linkend="zend.controller.plugins">プラグインブローカ</link>
31 を持っています。これにより、さまざまなイベントをプラグインで処理できるようになります。
32 開発者は、ディスパッチ処理をカスタマイズして機能を追加する際に
33 フロントコントローラ自体を継承したクラスを作成する必要がなくなります。
37 <link linkend="zend.controller.action">アクションコントローラ</link>
38 へのパスを含むディレクトリを最低ひとつは指定しないと、
40 フロントコントローラの動作環境やそのヘルパークラスを変更するために、
45 <title>デフォルトの挙動</title>
48 <link linkend="zend.controller.plugins.standard.errorhandler">ErrorHandler</link>
50 <link linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>
51 アクションヘルパープラグインを読み込みます。
52 これらにより、コントローラ内でのエラー処理やビューのレンダリングがシンプルに行えるようになります。
56 <emphasis>ErrorHandler</emphasis> を無効にするには、
57 <methodname>dispatch()</methodname> をコールする前のどこかで以下のようにします。
60 <programlisting language="php"><![CDATA[
61 // ErrorHandler プラグインを無効にします
62 $front->setParam('noErrorHandler', true);
66 <emphasis>ViewRenderer</emphasis> を無効にするには、
67 <methodname>dispatch()</methodname> をコールする前に以下を実行します。
70 <programlisting language="php"><![CDATA[
71 // ViewRenderer ヘルパーを無効にします
72 $front->setParam('noViewRenderer', true);
77 <sect2 id="zend.controller.front.methods.primary">
78 <title>主要なメソッド</title>
81 フロントコントローラには、その環境設定用のメソッドがいくつか用意されています。
82 そのうち、フロントコントローラの機能の鍵となる主要なメソッドは、以下の3つです。
85 <sect3 id="zend.controller.front.methods.primary.getinstance">
86 <title>getInstance()</title>
89 <methodname>getInstance()</methodname> は、フロントコントローラのインスタンスを取得します。
90 フロントコントローラはシングルトンパターンを実装しているので、
91 フロントコントローラのインスタンスを作成する唯一の方法はこのメソッドをコールすることとなります。
94 <programlisting language="php"><![CDATA[
95 $front = Zend_Controller_Front::getInstance();
99 <sect3 id="zend.controller.front.methods.primary.setcontrollerdirectory">
100 <title>setControllerDirectory() および addControllerDirectory</title>
103 <methodname>setControllerDirectory()</methodname> は、<link
104 linkend="zend.controller.dispatcher">ディスパッチャ</link>
106 linkend="zend.controller.action">アクションコントローラ</link>
107 クラスファイルをどこから探せばよいのかを指定するメソッドです。
108 単一のパスを指定することもできますし、複数のパスを連想配列で指定することもできます。
115 <programlisting language="php"><![CDATA[
116 // デフォルトのコントローラディレクトリを設定します
117 $front->setControllerDirectory('../application/controllers');
119 // 複数のモジュールのディレクトリを一度に指定します
120 $front->setControllerDirectory(array(
121 'default' => '../application/controllers',
122 'blog' => '../modules/blog/controllers',
123 'news' => '../modules/news/controllers',
126 // 'foo' モジュールのディレクトリを追加します
127 $front->addControllerDirectory('../modules/foo/controllers', 'foo');
132 <methodname>addControllerDirectory()</methodname>
133 でモジュール名を省略すると、<emphasis>default</emphasis>
135 もしすでに存在する場合は、それを上書きします。
140 コントローラディレクトリの現在の設定を取得するには
141 <methodname>getControllerDirectory()</methodname> を使用します。
142 これは、モジュールとディレクトリの組を配列で返します。
146 <sect3 id="zend.controller.front.methods.primary.addmoduledirectory">
147 <title>addModuleDirectory() および getModuleDirectory()</title>
150 フロントコントローラのひとつの側面として、<link
151 linkend="zend.controller.modular">モジュラーディレクトリ構造を定義
152 </link> して単体のコンポーネントを作成するということがあります。
157 書くモジュールは個別のディレクトリになければならず、
158 またデフォルトモジュールと同じディレクトリ構成でなければなりません。
159 すなわち、すくなくともサブディレクトリ <filename>/controllers/</filename> がなければならず、
160 またたいていは <filename>/views/</filename> などの他のサブディレクトリもあるということです。
164 <methodname>addModuleDirectory()</methodname>
165 には、ひとつあるいは複数のモジュールディレクトリの名前を渡します。
166 渡された内容を調べ、それをフロントコントローラのコントローラディレクトリに追加します。
170 その後、特定のモジュールや現在のモジュールへのパスを知りたい場合に
171 <methodname>getModuleDirectory()</methodname> をコールします。
172 モジュール名を渡すと、指定したモジュールのディレクトリを取得することができます。
176 <sect3 id="zend.controller.front.methods.primary.dispatch">
177 <title>dispatch()</title>
180 <methodname>dispatch(Zend_Controller_Request_Abstract $request = null,
181 Zend_Controller_Response_Abstract $response = null)</methodname>
182 は、フロントコントローラでもっとも重要な仕事を担当します。
183 オプションで <link linkend="zend.controller.request">リクエストオブジェクト</link>
184 や <link linkend="zend.controller.response">レスポンスオブジェクト</link>
185 を受け取り、それぞれ独自のオブジェクトを指定することができます。
189 リクエストオブジェクトやレスポンスオブジェクトを省略すると、
190 <methodname>dispatch()</methodname> は事前にオブジェクトが登録されているかどうかを確認します。
191 もし登録されていればそれを使用し、登録されていなければデフォルトのオブジェクトを作成して使用します
192 (どちらの場合についても、<acronym>HTTP</acronym> リクエスト/レスポンス オブジェクトをデフォルトで使用します)。
196 同様に、<methodname>dispatch()</methodname> は <link
197 linkend="zend.controller.router">ルータ</link> や <link
198 linkend="zend.controller.dispatcher">ディスパッチャ</link>
199 オブジェクトについても登録済みのものがあるかどうかを確認します。
200 もしあればそれを使用し、なければデフォルトのオブジェクトを作成して使用します。
204 ディスパッチ処理は、次の三段階に分けられます。
208 <listitem><para>ルーティング</para></listitem>
209 <listitem><para>ディスパッチ</para></listitem>
210 <listitem><para>レスポンス</para></listitem>
214 ルーティングは一度だけ発生します。これは、<methodname>dispatch()</methodname>
215 がコールされた際のリクエストオブジェクトの内容を使用して行います。
217 ひとつのリクエストが複数のアクションを指定している場合や、
218 コントローラまたはプラグインがリクエストオブジェクトを設定しなおして
219 別のアクションへディスパッチさせた場合などです。
220 すべてが終了したら、フロントコントローラはレスポンスを返します。
224 <sect3 id="zend.controller.front.methods.primary.run">
228 <methodname>Zend_Controller_Front::run($path)</methodname>
229 は静的メソッドで、コントローラを含むディレクトリへのパスを指定します。
231 <link linkend="zend.controller.front.methods.primary.getinstance">getInstance()</link>
232 を使用してフロントコントローラのインスタンスを取得し、
233 <link linkend="zend.controller.front.methods.primary.setcontrollerdirectory">setControllerDirectory()</link>
235 <link linkend="zend.controller.front.methods.primary.dispatch">ディスパッチ</link>
240 <methodname>run()</methodname> は、サイト単位の設定などで
241 フロントコントローラのカスタマイズが不要な場合に便利なメソッドです。
244 <programlisting language="php"><![CDATA[
245 // フロントコントローラを作成してコントローラディレクトリを設定し、
246 // ディスパッチするまでをいちどでお手軽に行います
247 Zend_Controller_Front::run('../application/controllers');
252 <sect2 id="zend.controller.front.methods.environment">
253 <title>環境へのアクセス用メソッド群</title>
256 これまでに説明したメソッド以外にもさまざまなアクセス用メソッドが用意されており、
257 これらを使用してフロンとコントローラの環境にアクセスすることができます。
258 つまり、フロントコントローラが処理を委譲しているクラスの環境にもアクセスできるということです。
264 <methodname>resetInstance()</methodname> は、現在の設定をすべて消去します。
266 複数のフロントコントローラを連結させたい場合などに使用することもあります。
272 <methodname>setDefaultControllerName()</methodname> および
273 <methodname>getDefaultControllerName()</methodname>
274 で、デフォルトのコントローラとして使用する名前を指定したり
275 (指定しなければ 'index' となります) 現在の設定を取得したりできます。
276 これらメソッドは、<link linkend="zend.controller.dispatcher">
277 ディスパッチャ</link> へのプロキシです。
283 <methodname>setDefaultAction()</methodname> および
284 <methodname>getDefaultAction()</methodname>
285 で、デフォルトのアクションとして使用する名前を指定したり
286 (指定しなければ 'index' となります) 現在の設定を取得したりできます。
287 これらのメソッドは <link linkend="zend.controller.dispatcher">
288 ディスパッチャ</link> へのプロキシです。
294 <methodname>setRequest()</methodname> および
295 <methodname>getRequest()</methodname> は、ディスパッチ処理で使用する
296 <link linkend="zend.controller.request">リクエスト</link>
297 クラスやオブジェクトを指定したり、現在のオブジェクトを取得したりします。
298 リクエストオブジェクトを指定するときに、クラス名を指定することができます。
299 この場合、このメソッドは指定したクラスファイルを読み込んでインスタンスを作成します。
305 <methodname>setRouter()</methodname> および
306 <methodname>getRouter()</methodname> は、ディスパッチ処理で使用する
307 <link linkend="zend.controller.router">ルータ</link>
308 クラスやオブジェクトを指定したり、現在のオブジェクトを取得したりします。
309 ルータオブジェクトを指定するときに、クラス名を指定することができます。
310 この場合、このメソッドは指定したクラスファイルを読み込んでインスタンスを作成します。
314 ルータオブジェクトを取得する際には、まずルータが存在するかどうかを調べ、
315 存在しない場合にはデフォルトのルータ (rewrite ルータ) のインスタンスを作成します。
321 <methodname>setBaseUrl()</methodname> および
322 <methodname>getBaseUrl()</methodname> は、リクエストのルーティング時に <acronym>URL</acronym> から取り除く
323 <link linkend="zend.controller.request.http.baseurl">基底 <acronym>URL</acronym></link>
324 を指定したり、現在の値を取得したりします。
325 この値は、ルーティングの直前にリクエストオブジェクトに渡されます。
331 <methodname>setDispatcher()</methodname> および
332 <methodname>getDispatcher()</methodname> は、ディスパッチ処理で使用する
333 <link linkend="zend.controller.dispatcher">ディスパッチャ</link>
334 クラスやオブジェクトを指定したり、現在のオブジェクトを取得したりします。
335 ディスパッチャオブジェクトを指定するときに、クラス名を指定することができます。
336 この場合、このメソッドは指定したクラスファイルを読み込んでインスタンスを作成します。
340 ディスパッチャオブジェクトを取得する際には、まずディスパッチャが存在するかどうかを調べ、
341 存在しない場合にはデフォルトのディスパッチャのインスタンスを作成します。
347 <methodname>setResponse()</methodname> および
348 <methodname>getResponse()</methodname> は、ディスパッチ処理で使用する
349 <link linkend="zend.controller.response">レスポンス</link>
350 クラスやオブジェクトを指定したり、現在のオブジェクトを取得したりします。
351 レスポンスオブジェクトを指定するときに、クラス名を指定することができます。
352 この場合、このメソッドは指定したクラスファイルを読み込んでインスタンスを作成します。
358 <methodname>registerPlugin(Zend_Controller_Plugin_Abstract $plugin, $stackIndex = null)</methodname>
359 は、<link linkend="zend.controller.plugins">プラグインオブジェクト</link>
360 を登録します。オプションの <varname>$stackIndex</varname>
361 を設定すると、プラグインの実行順を制御することができます。
367 <methodname>unregisterPlugin($plugin)</methodname> は、
368 <link linkend="zend.controller.plugins">プラグインオブジェクト</link>
369 の登録を解除します。<varname>$plugin</varname>
370 にはプラグインオブジェクトそのものか、あるいはプラグインのクラス名を表す文字列を指定します。
371 ここで指定したプラグインの登録を解除します。
377 <methodname>throwExceptions($flag)</methodname> で、ディスパッチの際に発生した例外をスローするかどうかを切り替えます。
379 <link linkend="zend.controller.response">レスポンスオブジェクト</link>
380 に保存されます。<methodname>throwExceptions()</methodname>
385 詳細は <link linkend="zend.controller.exceptions">MVC
392 <methodname>returnResponse($flag)</methodname> は、フロントコントローラが
393 <methodname>dispatch()</methodname> からのレスポンスを返す (<constant>TRUE</constant>)
394 かレスポンスを自動的に発行する (<constant>FALSE</constant>)
395 かを切り替えます。デフォルトでは、レスポンスは
396 (<methodname>Zend_Controller_Response_Abstract::sendResponse()</methodname> によって)
397 自動的に発行されます。<methodname>returnResponse()</methodname>
404 実際に発行する前に例外のチェックを行いたり
405 レスポンスの情報 (ヘッダなど) をログに記録したりなどが考えられます。
411 <sect2 id="zend.controller.front.methods.params">
412 <title>フロントコントローラのパラメータ</title>
415 最初のほうで、フロントコントローラはレジストリとしても使用できると説明しました。
416 その際に使用するのが "param" 系のメソッド群です。
417 これらのメソッドを使用すると、任意のデータ (オブジェクトや変数)
418 をフロントコントローラに登録することができます。
419 登録したデータは、ディスパッチチェイン内のどこででも使用できます。
420 これらの値は、ルータやディスパッチャそしてアクションコントローラにも渡されます。
427 <methodname>setParam($name, $value)</methodname> は、
428 パラメータ <varname>$name</varname> の値を
429 <varname>$value</varname> に設定します。
435 <methodname>setParams(array $params)</methodname> は、
436 連想配列を使用して複数のパラメータを一度に設定します。
442 <methodname>getParam($name)</methodname> は、
443 <varname>$name</varname> で指定した名前のパラメータの値を取得します。
449 <methodname>getParams()</methodname> は、
450 すべてのパラメータの一覧を一度に取得します。
456 <methodname>clearParams()</methodname> は、
457 単一のパラメータ (文字列で指定した場合) か
458 複数のパラメータ (文字列の配列で指定した場合)、
459 またはすべてのパラメータ (何も指定しなかった場合)
466 ディスパッチチェイン内で特定の目的で使用するために、
467 いくつかのパラメータが事前に定義されています。
473 <emphasis>useDefaultControllerAlways</emphasis> は、
475 (モジュール、コントローラ、アクションのいずれかが存在しない)
477 デフォルトモジュールのデフォルトコントローラにディスパッチするよう
478 <link linkend="zend.controller.dispatcher">ディスパッチャ</link>
479 に指示します。デフォルトではこの機能は無効になっています。
484 <link linkend="zend.controller.exceptions.internal">
485 遭遇するであろう MVC 例外</link>
492 <emphasis>disableOutputBuffering</emphasis> は、
493 アクションコントローラの出力をバッファリングしないよう
494 <link linkend="zend.controller.dispatcher">ディスパッチャ</link>
496 ディスパッチャがいったんすべての出力をキャプチャして、
503 <emphasis>noViewRenderer</emphasis> を使用して、<link
504 linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>
505 を無効にします。このパラメータを <constant>TRUE</constant> に設定すると、無効となります。
511 <emphasis>noErrorHandler</emphasis> を使用して、<link
512 linkend="zend.controller.plugins.standard.errorhandler">
513 エラーハンドラプラグイン</link> を無効にします。
514 このパラメータを <constant>TRUE</constant> に設定すると、無効となります。
520 <sect2 id="zend.controller.front.subclassing">
521 <title>フロントコントローラの継承</title>
525 最低限 <methodname>getInstance()</methodname> メソッドをオーバーライドしなければなりません。
528 <programlisting language="php"><![CDATA[
529 class My_Controller_Front extends Zend_Controller_Front
531 public static function getInstance()
533 if (null === self::$_instance) {
534 self::$_instance = new self();
537 return self::$_instance;
543 <methodname>getInstance()</methodname> メソッドをオーバーライドすることで、それ以降の
544 <methodname>Zend_Controller_Front::getInstance()</methodname> のコールが
545 <classname>Zend_Controller_Front</classname> ではなく新しいサブクラスのインスタンスを返すようになります。
546 これは、デフォルト以外のルータやビューヘルパーを使用する場合などに便利です。
550 何か新しい機能 (たとえばプラグインの自動ローダーや、
553 ふつうはフロントコントローラのサブクラスを作成する必要はありません。
556 デフォルトルータ/デフォルトディスパッチャを使用するかどうかなどがあるでしょう。