Programmer's Reference Guide
| アクションコントローラ |
アクションヘルパー
導入
アクションヘルパーを使用すると、Zend_Controller_Action を継承した任意のアクションコントローラに対して 実行時やその他必要に応じて機能追加をすることができます。 アクションヘルパーの狙いは、 アクションコントローラに共通機能を追加するために いちいち抽象クラスを継承する手間を省くことにあります。
アクションヘルパーにはさまざまな使用法があります。
たとえば、Zend_View_Helpers
や Zend_Controller_Plugin
と同じように、処理の仲買をするために用いることもできます。
アクションヘルパーは (Zend_View_Helpers と同様に)、
必要になった時点で読み込むこともできますし、
リクエスト時 (起動時) やアクションコントローラの作成時 (init())
で読み込むこともできます。詳細は、以下の使用例を参照ください。
ヘルパーの初期化
ヘルパーを初期化するにはいくつかの方法があります。 必要に応じて、またそのヘルパーの機能に応じて使い分けましょう。
ヘルパーブローカは、Zend_Controller_Action
の $_helper に格納されます。
このブローカを使用して、ヘルパーを取得したりコールしたりします。
以下のような方法があります。
-
明示的に
getHelper()を使用します。 ヘルパーの名前を指定すると、 そのヘルパーオブジェクトが返されます。<?php $flashMessenger = $this->_helper->getHelper('FlashMessenger'); $flashMessenger->addMessage('先ほどのリクエストで、あることをしました'); -
ヘルパーブローカの
__get()機能を使用すると、 まるでブローカのプロパティであるかのようにヘルパーを操作できます。<?php $flashMessenger = $this->_helper->FlashMessenger; $flashMessenger->addMessage('先ほどのリクエストで、あることをしました'); -
たいていのアクションヘルパーは
direct()メソッドを実装しており、 これはそのヘルパーのデフォルトメソッドをコールします。FlashMessengerの例では、addMessage()をコールします。<?php $this->_helper->FlashMessenger('先ほどのリクエストで、あることをしました');
注意: これらの例は、すべて同じことを行っています。
ヘルパーのインスタンスを明示的に作成したいと考えるかもしれません。 たとえばアクションコントローラ以外からヘルパーを使用したいだとか、 すべてのアクションのヘルパーブローカに同じヘルパーを渡したいだとかいった場合です。 インスタンスを作成する方法は、通常の PHP のクラスと同じです。
ヘルパーブローカ
Zend_Controller_Action_HelperBroker
がヘルパーオブジェクトやそのパスの登録に関する詳細を処理します。
また、必要に応じてそこからヘルパーを取得することができます。
ヘルパーをブローカに登録するには
addHelper を使用します。
<?php
Zend_Controller_Action_HelperBroker::addHelper($helper);
もちろん、ヘルパーのインスタンスを作成してそれをブローカに渡すという作業は
時間とリソースを消費します。これらの作業の手間をほんの少し省くためのメソッドとして、
addPrefix() と
addPath() が用意されています。
-
addPrefix()はクラスのプレフィックスを受け取り、 それをもとにヘルパークラスのパスを決定します。 プレフィックスが、Zend Framework のクラス命名規約に沿っているものとみなして、 パスを決定します。<?php // My/Action/Helpers/ にある、名前が My_Action_Helpers で始まるヘルパーを追加します Zend_Controller_Action_HelperBroker::addPrefix('My_Action_Helpers'); -
addPath()は、最初の引数にディレクトリ、 そして二番目の引数にクラスのプレフィックス (デフォルトは 'Zend_Controller_Action_Helper') を指定します。 これは、指定したディレクトリにある指定したプレフィックスのクラスを追加します。<?php // Plugins/Helpers/ にある、名前が Helper で始まるヘルパーを追加します Zend_Controller_Action_HelperBroker::addPath('./Plugins/Helpers', 'Helper');
これらは静的メソッドなので、コントローラチェイン内の任意の場所で使用することができます。 これにより、必要に応じて動的にヘルパーを追加できることになります。
ヘルパークラスがヘルパーブローカ内に存在するかどうかを調べるには
hasHelper($name) を使用します。$name
には、ヘルパーのショートネーム (プレフィックスを除いたもの)
を指定します。
<?php
// 'redirector' ヘルパーがブローカに登録されているかどうかを調べます
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
echo 'Redirector helper registered';
}
最後に、登録済みのヘルパーをブローカから削除するには
removeHelper($name) を使用します。$name
には、ヘルパーのショートネーム (プレフィックスを除いたもの)
を指定します。
<?php
// 'redirector' ヘルパーがブローカに登録されている場合にはそれを削除します
if (Zend_Controller_Action_HelperBroker::hasHelper('redirector')) {
Zend_Controller_Action_HelperBroker::removeHelper('redirector')
}
組み込みのアクションヘルパー
Zend Framework には、デフォルトで三種類のアクションヘルパーが組み込まれています。
セッション単位のフラッシュメッセージを扱う FlashMessenger と、
アプリケーション内から内部あるいは外部へのリダイレクトを実装できるようにする
Redirector、そして、
コントローラ内でのビューオブジェクトの設定とビューのレンダリングを自動化する
ViewRenderer です。
FlashMessenger
導入
FlashMessenger ヘルパーは、
次のリクエストの際にユーザに見せる必要のあるメッセージを渡すためのものです。
この機能を実現するため、FlashMessenger は
Zend_Session_Namespace を使用してメッセージを保管しています。
Zend_Session や
Zend_Session_Namespace を使用する際には、起動ファイル中で
Zend_Session::start() を実行するようにしましょう
(詳細な使用例は Zend Session
のドキュメントを参照ください)。
基本的な使用例
以下の使用例は、もっとも基本的なフラッシュメッセンジャーの使用法を示すものです。
アクション /some/my がコールされると、フラッシュメッセージに
"Record Saved!" が保存されます。そして、その次のアクション
/some/my-next-request へのリクエストの際にそれを取得
(そして削除) します。
<?php
class SomeController extends Zend_Controller_Action
{
/**
* FlashMessenger
*
* @var Zend_Controller_Action_Helper_FlashMessenger
*/
protected $_flashMessenger = null;
public function init()
{
$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
$this->initView();
}
public function myAction()
{
/**
* Zend_Controller_Action_Helper_FlashMessenger
* のインスタンスを必要に応じて取得するためのデフォルトメソッド
*/
$this->_flashMessenger->addMessage('Record Saved!');
}
public function myNextRequestAction()
{
$this->view->messages = $this->_flashMessenger->getMessages();
$this->render();
}
}
Redirector
導入
Redirector ヘルパーは、
アプリケーション内で必要となるリダイレクト処理用のオブジェクトとして使用します。
_redirect() メソッドと比べた場合の利点としては、
サイト全体で使用する設定を事前に組み込んでおけることがあります。また、
Zend_Controller_Action::_forward()
の場合と同様に、組み込みのインターフェイス
goto($action, $controller, $module, $params)
が使用できることも利点となります。
Redirector では、
リダイレクトの設定を行うメソッドとして次のようなものが用意されています。
-
setCode()を使用して、 リダイレクトの際に使用する HTTP レスポンスコードを設定します。 -
setExit()を使用して、 リダイレクトの後で強制的にexit()を実行させるようにします。 デフォルトは true です。 -
setGoto()を使用して、goto()に何も渡されなかったときのデフォルトの URL を設定します。Zend_Controller_Action::_forward()の API である setgoto($action, $controller = null, $module = null, array $params = array()); を使用します。 -
setGotoRoute()を使用して、 登録済みのルートにもとづいた URL を設定します。 キー/値 のペアの配列とルート名を渡し、 それをもとにルートの型と定義から URL を作成します。 -
setGotoUrl()を使用して、gotoUrl()に何も渡されなかったときのデフォルトの URL を設定します。 URL を表す文字列を受け取ります。 -
setPrependBase()を使用して、setGotoUrl()、gotoUrl()あるいはgotoUrlAndExit()で指定した URL の前にリクエストのベース URL を追加します。 -
setUseAbsoluteUri()を使用すると、Redirectorがリダイレクトの際に絶対 URL を使用するようになります。 このオプションを設定すると、$_SERVER['HTTP_HOST']や$_SERVER['SERVER_PORT']、そして$_SERVER['HTTPS']の内容をもとにして リダイレクト用の完全な URL を作成します。 このオプションのデフォルト値はオフですが、 将来のリリースではデフォルトで有効になるかもしれません。
さらに、実際のリダイレクトを行うためのメソッドとして以下のものが用意されています。
-
goto()は、setGoto()(_forward() 風の API) を用いて作成した URL にリダイレクトします。 -
gotoRoute()は、setGotoRoute()(ルートの作成) を用いて作成した URL にリダイレクトします。 -
gotoUrl()はsetGotoUrl()(URL 文字列の指定) を用いて作成した URL にリダイレクトします。
リダイレクト先の URL を知るには
getRedirectUrl() を使用します。
これはいつでも使用できます。
基本的な使用例
例1 オプションの設定
この例ではデフォルトのオプションを少し変更します。 HTTP ステータスコードを 303 にし、リダイレクト後に exit() しないようにして、そしてリダイレクトの際のデフォルト URL を指定しています。
<?php
class SomeController extends Zend_Controller_Action
{
/**
* Redirector - defined for code completion
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
// リダイレクタのデフォルトのオプションを設定します
// このオブジェクトはヘルパーブローカに登録されるので、
// これ以降のすべてのアクションで有効となります
$this->_redirector->setCode('303')
->setExit(false)
->setGoto("this-action", "some-controller");
}
public function myAction()
{
/* 何かを行います */
// 先ほど登録した URL にリダイレクトし、その後で
// exit() します
$this->_redirector->redirectAndExit();
return; // 決してここには到達しません
}
}
例2 デフォルト設定の使用
この例ではデフォルト設定を使用しています。
つまり、リダイレクトするとすぐに
exit() が実行されるということです。
<?php
// 別の例
class AlternativeController extends Zend_Controller_Action
{
/**
* Redirector - defined for code completion
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function myAction()
{
/* 何かを行います */
$this->_redirector->gotoUrl('/my-controller/my-action/param1/test/param2/test2');
return; // リダイレクト後に自動的に exit() されるので、決してここには到達しません
}
}
例3 goto() での _forward() API の使用
goto() の API は、
Zend_Controller_Action::_forward()
と同じ形式です。違う点は、このメソッドは渡されたパラメータから URL
を作成し、デフォルトルータのデフォルトフォーマットである
:module/:controller/:action/* を使用するということです。
また、アクションチェインではなくリダイレクトを行います。
<?php
class ForwardController extends Zend_Controller_Action
{
/**
* Redirector - defined for code completion
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function myAction()
{
/* 何かを行います */
// 現在のモジュールの 'my-controller' コントローラの
// 'my-action' アクションにリダイレクトします。
// パラメータは param1 => test、param2 => test2 となります。
$this->_redirector->goto('my-action', 'my-controller', null, array('param1' => 'test', 'param2' => 'test2'));
}
}
例4 gotoRout() でのルートアセンブリの使用
次の例は、ルータ
の assemble() メソッドを使用して、
パラメータで指定した連想配列に基づく URL を作成しています。
次のようなルートが登録されているものと仮定します。
<?php
$route = new Zend_Controller_Router_Route(
'blog/:year/:month/:day/:id',
array('controller' => 'archive', 'module' => 'blog', 'action' => 'view')
);
$router->addRoute('blogArchive', $route);
?>
year を 2006、month を 4、そして day を 24
として配列を渡すと、結果の URL は
/blog/2006/4/24/42 となります。
<?php
class BlogAdminController extends Zend_Controller_Action
{
/**
* Redirector - defined for code completion
*
* @var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function returnAction()
{
/* 何かを行います */
// blog の過去記事にリダイレクトします。URL は
// /blog/2006/4/24/42 になります。
$this->_redirector->gotoRoute(
array('year' => 2006, 'month' => 4, 'day' => 24, 'id' => 42),
'blogArchive'
);
}
}
ViewRenderer
導入
ViewRenderer ヘルパーは、
以下のような要件を満たすために作られたものです。
-
コントローラ内でいちいちビューオブジェクトのインスタンスを 作成しなくても済むようにする。 ビューオブジェクトは自動的にコントローラに登録されます。
-
ビュースクリプトやヘルパー、そしてフィルタのパスを 現在のモジュールに基づいて自動的に設定し、 モジュール名をヘルパーやフィルタのクラス名の先頭に自動的に関連付ける。
-
すべてのコントローラとアクションで使用できる グローバルなビューオブジェクトを作成する。
-
すべてのコントローラで使用する、 デフォルトのビューレンダリングオプションを設定できるようにする。
-
何も指定しなくても、 自動的にビュースクリプトをレンダリングできる機能を追加する。
-
ビューの基底パスやビュースクリプトのパスを 独自に指定できるようにする。
注意:
_forward()やリダイレクト、あるいは手動でのレンダリングを行う場合は、 自動レンダリングは不要です。これらの処理を行う場合は、 出力を自前で行うことをViewRendererに対して指示します。
注意:
ViewRendererはデフォルトで有効になっています。 これを無効にするには、フロントコントローラのパラメータnoViewRendererを指定する ($front->setParam('noViewRenderer', true)) か、 あるいはヘルパーブローカからヘルパーを削除 (Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer')) します。
フロントコントローラでのディスパッチ処理の前にViewRendererの設定を変更したい場合は、 次のいずれかの方法を使用します。
独自の
ViewRendererのインスタンスを作成し、 ヘルパーブローカにそれを渡して登録する。<?php $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer(); $viewRenderer->setView($view) ->setViewSuffix('php'); Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
ViewRendererオブジェクトを、 ヘルパーブローカから必要に応じて作成、取得する。<?php $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $viewRenderer->setView($view) ->setViewSuffix('php');
API
もっとも基本的な使用法は、単に ViewRenderer
のインスタンスを作成してそれをヘルパーブローカに渡すというものです。
インスタンスの作成と登録を一度に行うには、ヘルパーブローカの
getStaticHelper() メソッドを使用するのがいちばん簡単です。
<?php
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
アクションコントローラのインスタンスが最初に作成されたときに、
ViewRenderer がビューオブジェクトのインスタンスを作成します。
コントローラのインスタンスが作成されるたびに、ViewRenderer
の init() がコールされます。
ここでアクションコントローラのビュープロパティを設定し、
現在のモジュールからの相対パスを指定して
addScriptPath() をコールします。
これは現在のモジュール名に基づいたプレフィックスをクラス名の先頭につけてコールされるので、
ヘルパーやフィルタのクラスをモジュール内で効率的に管理することができます。
postDispatch() がコールされるたびに、現在のアクションの
render() を自動的にコールします。
例として、次のようなクラスを考えてみましょう。
<?php
// foo モジュールのコントローラクラス
class Foo_BarController extends Zend_Controller_Action
{
// デフォルトで bar/index.phtml をレンダリングするので、特に何もする必要はありません
public function indexAction()
{
}
// 変数 'foo' の値を 'bar' に設定して bar/populate.phtml をレンダリングします
// ビューオブジェクトは既に preDispatch() で定義されているので、既に使用可能です
public function populateAction()
{
$this->view->foo = 'bar';
}
}
...
// ビュースクリプトの中では、たとえば次のように書きます
<?php $this->foo(); // Foo_View_Helper_Foo::foo() をコールします
ViewRenderer には、
ビューのオプションを取得したり設定したりするためのメソッドも豊富に用意されています。
-
setView($view)はViewRendererが使用するビューオブジェクトを設定します。 これは、クラスのプロパティ$viewの値を設定します。 -
setNeverRender($flag = true)を使用すると、自動レンダリング機能を全体的に (すべてのコントローラに対して)無効にしたり有効にしたりできます。 true を指定すると、そのコントローラのpostDispatch()ではrender()をコールしなくなります。getNeverRender()は、現在の設定を取得します。 -
setNoRender($flag = true)を使用すると、自動レンダリングを無効にしたり有効にしたりできます。 true を指定すると、現在のコントローラのpostDispatch()ではrender()をコールしなくなります。 この設定は、preDispatch()がコールされるたびにいったんリセットされます (つまり、自動レンダリングを無効にしたいすべてのコントローラで 個々にこれを設定する必要があるということです)。getNoRender()は、現在の設定を取得します。 -
setNoController($flag = true)を使用すると、render()がコントローラ名のサブディレクトリにあるアクションスクリプトを 読みにいかなくすることができます (デフォルトでは読みにいきます)。getNoController()は、現在の設定を取得します。 -
setNeverController($flag = true)はsetNoController()と似ていますが、 こちらは全体に影響を与えます。つまり、 ディスパッチ処理を行っても設定はリセットされません。getNeverController()は、現在の設定を取得します。 -
setScriptAction($name)を使用すると、レンダリングするアクションスクリプトを指定することができます。$nameは、スクリプト名から拡張子を除いたもの (そして、noControllerが指定されていない限り、 コントローラのディレクトリ名も除いたもの) となります。 指定しなかった場合は、リクエストオブジェクト内のアクションに基づいた名前の ビュースクリプトを探します。getScriptAction()は、現在の設定を取得します。 -
setResponseSegment($name)を使用すると、レンダリング結果を出力する レスポンスオブジェクトのセグメント名を指定することができます。 指定しなかった場合は、デフォルトのセグメントにレンダリングします。getResponseSegment()は、現在の設定を取得します。 -
initView($path, $prefix, $optionsは、ビューの基底パスを指定します。 また、ヘルパースクリプトとフィルタスクリプトの先頭につけるクラスプレフィックスやViewRendererのオプションも設定します。 オプションには、neverRender、noRender、noController、scriptActionおよびresponseSegmentのいずれかのフラグを指定します。 -
setRender($action = null, $name = null, $noController = false)を使用すると、scriptActionやresponseSegmentそしてnoControllerのいずれかまたは複数を 一度に指定することができます。direct()はこのメソッドのエイリアスで、コントローラ内から簡単にコールすることができます。// 現在のアクションスクリプトではなく 'foo' をレンダリングします $this->_helper->viewRenderer('foo'); // form.phtml の内容をレスポンスセグメント 'html' にレンダリングします。 // コントローラのビュースクリプト用サブディレクトリは使用しません。 $this->_helper->viewRenderer('form', 'html', true);注意:
setRender()およびdirect()は、実際にはビュースクリプトをレンダリングしません。 実際にレンダリングを行うのはpostDispatch()やrender()で、それらのメソッドに対するヒントを指示するだけです。
コンストラクタのオプションとして、
ビューオブジェクトを渡したり ViewRenderer
のオプションを渡したりすることができます。
このオプションで指定できるのは、initView()
で説明したフラグと同じものです。
$view = new Zend_View(array('encoding' => 'UTF-8'));
$options = array('noController' => true, 'neverRender' => true);
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view, $options);
さらに追加のメソッドがあり、 ビューオブジェクトで使用するビューの基底パスを変更することができます。 また、ビュースクリプトが自動レンダリングを行う際に使用するパスも変更することができます。 これらのメソッドでは、以下のプレースホルダのいずれかあるいは複数が使用できます。
-
:moduleDirは、現在のモジュールの基底ディレクトリを指します (規約では、これはモジュールのコントローラディレクトリの親ディレクトリとなります)。 -
:moduleは、現在のモジュール名を指します。 -
:controllerは、現在のコントローラ名を指します。 -
:actionは、現在のアクション名を指します。 -
:suffixは、ビュースクリプトのサフィックス (setViewSuffix()で設定したもの) を指します。
パス指定を制御するメソッドは次のとおりです。
-
setViewBasePathSpec($spec)は、ビューオブジェクトを追加する際に使用する基底パスを 決める際に使用するパス指定を変更します。 デフォルトの設定は:moduleDir/viewsです。 現在の設定を取得するにはgetViewBasePathSpec()を使用します。 -
setViewScriptPathSpec($spec)は、個々のビュースクリプトのパス (からビュースクリプトの基底パスを除いた部分) を決める際に使用するパス指定を変更します。 デフォルトの設定は:controller/:action.:suffixです。 現在の設定を取得するにはgetViewScriptPathSpec()を使用します。 -
setViewScriptPathNoControllerSpec($spec)は、noControllerが有効な場合に 個々のビュースクリプトのパス (からビュースクリプトの基底パスを除いた部分) を決める際に使用するパス指定を変更します。 デフォルトの設定は:action.:suffixです。 現在の設定を取得するにはgetViewScriptPathNoControllerSpec()を使用します。
ViewRenderer API の最後に紹介するのは、
実際にビュースクリプトのパスを決定するメソッドと
ビューのレンダリングを行うメソッドです。以下をご覧ください。
-
renderScript($script, $name)は、指定したパスのスクリプトをレンダリングします。 オプションで、パスセグメントの名前を指定することもできます。 このメソッドを使用する際には、ViewRendererはスクリプト名を自動的に決定することはありません。 そのかわりに、$scriptで指定された内容を直接 ビューオブジェクトのrender()メソッドに渡します。注意: レスポンスオブジェクトにビューがレンダリングされると、 自動的に
noRenderを設定します。 これにより、同じビュースクリプトを間違って複数回レンダリングしてしまうことを防ぎます。注意: デフォルトでは、
Zend_Controller_Action::renderScript()はViewRendererのrenderScript()メソッドへのプロキシとなります。
-
getViewScript($action, $vars)は、渡されたアクションや$varsで指定した変数の値に基づいてビュースクリプトのパスを作成します。$vars配列のキーは、パスを指定するためのキー ('moduleDir'、'module'、'controller'、'action' および 'suffix') のいずれかとなります。渡された変数の値をもとにしてパスを作成します。 なにも渡されなかった場合は、現在のリクエストの内容をもとにしてパスを作成します。getViewScript()は、noControllerフラグの内容によってviewScriptPathSpecあるいはviewScriptPathNoControllerSpecのいずれかを使用します。モジュール名やコントローラ名、アクション名にあらわれる 単語の区切りは、ダッシュ ('-') に置き換えられます。 したがって、たとえばコントローラ名が 'foo.bar' でアクション名が 'baz:bat' だったとすると、 デフォルトのパス指定をもとにしたビュースクリプトのパスは 'foo-bar/baz-bat.phtml' となります。
注意: デフォルトでは、
Zend_Controller_Action::getViewScript()はViewRendererのgetViewScript()メソッドへのプロキシとなります。
-
render($action, $name, $noController)は、まず$nameあるいは$noControllerが指定されているかどうかを調べます。 指定されている場合は、ViewRenderer の対応するフラグ (それぞれ responseSegment と noController) を設定します。 次に、$action引数が指定されていれば、 それをgetViewScript()に渡します。 最後に、取得したビュースクリプトのパスをrenderScript()に渡します。注意: render() を使用する際には、その副作用に注意しましょう。 レスポンスセグメント名や noController フラグに指定した内容は、そのオブジェクト内で残り続けます。 さらに、レンダリングが完了した際に noRender も設定されます。
注意: デフォルトでは、
Zend_Controller_Action::render()はViewRendererのrender()メソッドへのプロキシとなります。
-
renderBySpec($action, $vars, $name)は、パス指定用の変数を渡してビュースクリプトのパスを決定します。$actionおよび$varsの内容をgetScriptPath()に、そしてその結果得られたスクリプトのパスと$nameをrenderScript()に渡します。
基本的な使用例
例5 基本的な使用法
最も基本的な使用法は、起動ファイル内で ViewRenderer
を作成してヘルパーブローカに登録し、
アクションメソッドで変数の値を設定するというものです。
<?php
// 起動ファイル内で
Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
...
<?php
// 'foo' モジュールの 'bar' コントローラ
class Foo_BarController extends Zend_Controller_Action
{
// デフォルトで bar/index.phtml をレンダリングするので、特に何もする必要はありません
public function indexAction()
{
}
// 変数 'foo' の値を 'bar' に設定して bar/populate.phtml をレンダリングします
// ビューオブジェクトは既に preDispatch() で定義されているので、既に使用可能です
public function populateAction()
{
$this->view->foo = 'bar';
}
// 何もレンダリングせずに別のアクションに転送します
// 転送先のアクションで何らかのレンダリングを行います
public function bazAction()
{
$this->_forward('index');
}
// 何もレンダリングせず別の場所にリダイレクトします
public function batAction()
{
$this->_redirect('/index');
}
}
注意: 命名規約: コントローラ名やアクション名の単語の区切り
コントローラやアクションの名前が複数の単語からなるものである場合、 ディスパッチャには、特定のパスや区切り文字を使用して単語を区切った URL を指定しなければなりません。ViewRendererは、コントローラ名の中にあるパス区切り文字を 実際のパス区切り文字 ('/') に置き換え、単語区切り文字をダッシュ ('-') に置き換えてパスを作成します。したがって、 アクション/foo.bar/baz.batをコールすると FooBarController.php のFooBarController::bazBatAction()へディスパッチされ、foo-bar/baz-bat.phtmlをレンダリングすることになります。 また、アクション/bar_baz/baz-batをコールするとBar/BazController.php(パス区切り文字に注意) のBar_BazController::bazBatAction()へディスパッチされ、bar/baz/baz-bat.phtmlをレンダリングすることになります。
二番目の例では、モジュールはデフォルトモジュールのままであることに注意しましょう。 しかし、パス区切り文字があるために、Bar/BazController.phpにあるBar_BazControllerを受け取ることになります。 ビューレンダラはコントローラのディレクトリ階層を模倣します。
例6 自動レンダリングの無効化
アクションやコントローラによっては、自動レンダリングを無効にしたいこともあるでしょう。
たとえば、HTML 以外 (XML や JSON など) を出力したい場合や
単に何も出力したくない場合などです。
そんな場合には以下のいずれかの方法を使用します。
つまり、すべての自動レンダリングを無効にする
(setNeverRender()) か、あるいは現在のアクションでだけ
自動レンダリングを無効にする (setNoRender()) かです。
<?php
// Bar モジュールの Baz コントローラクラス
class Bar_BazController extends Zend_Controller_Action
{
public function fooAction()
{
// このアクションでは自動レンダリングを行いません
$this->_helper->viewRenderer->setNoRender();
}
}
// Bar モジュールの Bat コントローラクラス
class Bar_BatController extends Zend_Controller_Action
{
public function preDispatch()
{
// このコントローラのアクションでは決して自動レンダリングを行いません
$this->_helper->viewRenderer->setNoRender();
}
}
注意: たいていの場合は、自動レンダリングを全体で無効にする (
setNeverRender()) のは無意味です。 なぜなら、ViewRendererの唯一の存在意義が、 ビューオブジェクトを自動的に設定することだからです。
例7 別のビュースクリプトの選択
アクション名から自動的に決まるスクリプトではなく、
それ以外のものをレンダリングしたくなる場合もあるでしょう。
たとえば、add アクションと edit アクションのふたつを持つコントローラがあったとしましょう。
どちらのアクションも同じ 'form' ビューを表示しますが、
そこに設定する値が異なります。
そんな場合に、それぞれでスクリプト名を変えるのは簡単です。
setScriptAction() や setRender()
を使用するか、あるいはヘルパーをメソッドとしてコールします。
これは setRender() を起動します。
<?php
// Foo モジュールの Bar コントローラクラス
class Foo_BarController extends Zend_Controller_Action
{
public function addAction()
{
// 'bar/add.phtml' ではなく 'bar/form.phtml' をレンダリングします
$this->_helper->viewRenderer('form');
}
public function editAction()
{
// 'bar/edit.phtml' ではなく 'bar/form.phtml' をレンダリングします
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// 何かのチェックをした後で...
if (!$valid) {
// 'bar/process.phtml' ではなく 'bar/form.phtml' をレンダリングします
$this->_helper->viewRenderer->setRender('form');
return;
}
// その他の処理を続けます...
}
}
例8 登録されているビューの変更
ビューオブジェクトの設定を変更したくなったとしましょう。
たとえば、ヘルパーのパスやエンコーディングを変更したくなったらどうしますか?
そんな場合は、コントローラに設定されているビューオブジェクトを変更するか、
あるいは ViewRenderer の外部からビューオブジェクトを取得します。
どちらも同じオブジェクトへの参照を取得することになります。
<?php
// Foo モジュールの Bar コントローラクラス
class Foo_BarController extends Zend_Controller_Action
{
public function preDispatch()
{
// ビューのエンコーディングを変更します
$this->view->setEncoding('UTF-8');
}
public function bazAction()
{
// ビューオブジェクトを取得し、エスケープ用のコールバックを 'htmlspecialchars' に設定します
$view = $this->_helper->viewRenderer->view;
$view->setEscape('htmlspecialchars');
}
}
高度な使用例
例9 パスの指定方法の変更
場合によっては、デフォルトのパス指定があなたのサイトに うまく当てはまらないこともあるでしょう。 たとえば、すべてのテンプレートを単一のディレクトリ配下にまとめ、 デザイナにはそのディレクトリに対するアクセス権だけを与えたいといった場合です (» Smarty を使用する場合などにありがちです)。 そんな場合は、ビューの基底パスをハードコーディングし、 それをアクションのビュースクリプトのパスとして使用することになります。
この例では、ビューの基底パスを '/opt/vendor/templates' とし、ビュースクリプトのパスは ':moduleDir/:controller/:action.:suffix' となるようにします。noController フラグが設定されている場合は、サブディレクトリ (':action.:suffix') からではなくトップディレクトリからのパスとして探すことになります。 最後に、ビュースクリプトのファイルの拡張子として 'tpl' を設定します。
<?php
/**
* 起動ファイル
*/
// 別のビュー実装を使用します
$view = new ZF_Smarty();
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewBasePathSpec('/opt/vendor/templates')
->setViewScriptPathSpec(':module/:controller/:action.:suffix')
->setViewScriptPathNoControllerSpec(':action.:suffix')
->setViewSuffix('tpl');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
例10 単一のアクションから複数のビュースクリプトをレンダリングする例
時には、複数のビュースクリプトをひとつのアクションで処理したいこともあるでしょう。
これは、非常に直感的な方法で実現できます。単に
render() を必要なだけコールすればいいのです。
<?php
class SearchController extends Zend_Controller_Action
{
public function resultsAction()
{
// $this->model に現在のモデルが設定されているものとします
$this->view->results = $this->model->find($this->_getParam('query', '');
// render() は、デフォルトでは ViewRenderer へのプロキシとなります。
// まず form を、そして results をレンダリングします
$this->render('form');
$this->render('results');
}
public function formAction()
{
// 何もしなくても、ViewRenderer が自動的にビュースクリプトをレンダリングします
}
}
独自のヘルパーの作成
アクションヘルパーは、抽象クラス
Zend_Controller_Action_Helper_Abstract
を継承して作成します。
ここには、基本的なインターフェイスやヘルパーブローカが使用する必須機能などが含まれています。
具体的には、次のようなメソッドです。
-
setActionController()を使用して、現在のアクションコントローラを設定します。 -
init()はヘルパーブローカによって起動時に実行され、 ヘルパーを初期化します。これは、 アクションチェイン内の複数のコントローラで同一のヘルパーを使用している場合に 状態をリセットする際などに便利です。 -
preDispatch()はディスパッチアクションの前に実行されます。 -
postDispatch()はディスパッチアクションが終了した後で実行されます。preDispatch()プラグインがアクションの処理をスキップした場合も、 これは実行されます。後始末などをここで行います。 -
getRequest()は現在のリクエストオブジェクトを取得します。 -
getResponse()は現在のレスポンスオブジェクトを取得します。 -
getName()はヘルパーの名前を取得します。 クラス名にアンダースコアが含まれる場合は最後のアンダースコア以降の文字、 そうでない場合はクラス名全体を返します。たとえば、クラス名がZend_Controller_Action_Helper_Redirectorの場合はRedirectorを、クラス名がFooMessageの場合はそのままの名前を返します。
オプションで、ヘルパークラスに direct()
メソッドを実装することもできます。これを定義しておくと、
ヘルパーブローカのメソッドであるかのようにそのヘルパーを扱えるようになります。
これにより、一度だけ使用するようなヘルパーが扱いやすくなります。
たとえば、redirector
の direct() は goto()
のエイリアスとなっているので、このようにして使用することができます。
<?php
// /blog/view/item/id/42 にリダイレクトします
$this->_helper->redirector('item', 'view', 'blog', array('id' => 42));
内部的には、まずヘルパーブローカの __call()
メソッドが redirector という名前のヘルパーを探し、
それからそのヘルパーで direct
メソッドが定義されているかどうかを調べ、
渡された引数でそのメソッドをコールしています。
独自のヘルパークラスを作成した場合は、 上で説明したようにしてそれを利用できるようにしておきましょう。
| アクションコントローラ |
