アクションコントローラ
フロントコントローラにおいてディスパッチされたリクエストを実際に処理するのが、アクションコントローラです。
例えばリクエストが「Codezine」コントローラの「display」アクションを要求している場合、通常ディスパッチの過程でコールされるのは、アクションコントローラにおける「CodezineController
」クラスの「displayAction()
」メソッドです(命名規則については前回を参照)。
Zend_Controller_Actionのサブクラスの作成/アクションメソッドの記述
アクションコントローラを使用するには、まずZend_Controller_Action
のサブクラスを作成するところから始まります。そしてサブクラスの中に最低一つ、アクションメソッドを用意する必要があります。前回触れたとおり、「IndexController
」「indexAction()
」はそれぞれデフォルトのクラス/アクションメソッドです(前出のサンプルのように、名前は変更することができます)。
またアクションコントローラ内には、アクションメソッド以外にもいくつかの特定の役割を持つメソッドを定義することができます。以下具体的に、メソッド(init()
、preDispatch()
、postDispatch()
)を解説していきます。これらのメソッドは、以下の順で実行されます。
init()
preDispatch()
- (アクションメソッド)
postDispatch()
アクションコントローラの初期化処理:init()
アクションコントローラにおいて何か特別な初期化作業を行いたい場合はinit()
メソッドを用います。これはアクションコントローラのコンストラクタの最後に呼び出されるものです。
class IndexController extends Zend_Controller_Action { public function init() { (初期化処理) } : :
ディスパッチ前後に行う処理:preDispatch()/postDispatch()
ディスパッチ処理の前後に、特定の処理を行うようにすることができます。例えば認証情報チェックやビューの仕上げの処理などです。これはリクエストされたアクション・メソッドの実行前後にそれぞれpreDispatch()
/postDispatch()
がコールされることで実現されます。この2つのメソッドに行いたい処理を記述します。
先ほどディスパッチの項で触れたフラグのリセットもここで可能です。それにより処理先のコントローラやアクション、パラメータを変更してリクエストを再度処理することが可能になります。それを実現するのが「_forward()
」メソッドです。以下に概要を示しておきます。_forward(アクション名,コントローラ名,モジュール名,パラメータ)
とすることで別のアクションの実行に移ります(もしアクションメソッド内でコールされれば、現在のアクションを実行し終えてから新たなアクションの実行へ移ります)。
preDispatch()
もinit()
もアクションメソッドに先立って実行されますが、preDispatch()
はinit()
の後に実行されます。
サンプル
以下にinit()
、preDispatch()
、_forward()
を利用したサンプルを示します。
<?php require_once 'Zend/Controller/Action.php'; require_once 'Zend/Date.php'; class InitsampleController extends Zend_Controller_Action { public function init() { $this->view->assign('message', '初期化処理を呼び出しました'); } public function preDispatch() { $date = new Zend_Date(); $this->view->assign('dt', $date->get(Zend_Date::TIMES)); if(($date->compare('09:00:00', Zend_Date::TIMES) < 0) ||($date->compare('17:00:00', Zend_Date::TIMES) > 0)) { // (1) $this->view->assign( 'message2', '営業時間は9時から17時までです'); $this->_forward('index','index'); // (2) } else { $this->view->assign('message2', 'いらっしゃいませ'); } } public function indexAction() { $this->view->assign('actionname', 'indexアクションです'); } public function index2Action() { $this->view->assign('actionname', 'index2アクションです'); } }
init()
メソッド内で初期化メッセージmessage
を格納し、その後のpreDispatch()
内においては (1) で現在時間を判断し9時~17時とそれ以外で処理を分けています。9時~17時でなければメッセージを入れ、(2) の「_forward()
」でindexコントローラ/indexアクションの実行へ移します(時刻処理についてはZend_Dateの回で解説予定です)。「http://localhost/initsample/」や「http://localhost/initsample/index2/」にアクセスしてみてください。以下、「http://localhost/initsample/」で2通りの時間帯にアクセスした結果を示します。
エラーコントローラ
前回少し触れましたが、デフォルトでは「ErrorHandler」プラグインが有効になっています。「ErrorHandler」プラグインは、指定されたアクションコントローラやアクションメソッドが見つからない時(404型エラー)や、それ以外にアクションコントローラ内で例外(500型エラー)が発生した時にエラーを処理するためのプラグインです。このプラグインを使用するには、以下のファイルを用意します。
ファイル | 説明 |
application/controllers/ErrorController.php | エラーコントローラファイル |
application/views/scripts/error/error.phtml | エラーコントローラ用ビューファイル(ViewRendererが有効な場合) |
エラーコントローラファイルには、errorアクションメソッドを用意します。
<?php require_once 'Zend/Controller/Action.php'; class ErrorController extends Zend_Controller_Action { public function errorAction() { //(エラー発生時の処理) $this->view->assign('errortype', $this->_getParam('error_handler')->type); } }
エラーが発生したことを表示するだけであれば、特に処理を記述する必要はありません。エラーを把握するには「Zend_Controller_Action::_getParam('error_handler')
」を使用します。上記では「$this->_getParam('error_handler')->type
」で、エラーの型を取得しています。具体的には次のような型が得られます。
EXCEPTION_NO_CONTROLLER
: コントローラが見つからないEXCEPTION_NO_ACTION
: アクションが見つからないEXCEPTION_OTHER
: その他の例外
また、ログに記録するような具体的な例外の内容は「$this->_getParam('error_handler')->exception
」で得ることができます。
errorAction()
に対応させるビューは「error.phtml」です。以下の例では取得したエラーの型を表示しています。
<html>
<head>
<title>エラー</title>
</head>
<body>
<h1>エラー</h1>
<p>エラーが発生しました。</p>
エラーの種類:<?php echo $this->escape($this->errortype);?><br />
</body>
</html>
試しに「http://localhost/initsample/wings」へアクセスしてみると、アクションが見つからないというエラーが発生するのが分かります。
アクセスメソッド/ユーティリティメソッド
この他、Zend_Controller_Action
には次のようなメソッドが用意されています。_forward()
については先ほどサンプルでも使いました。
メソッド | 内容 |
_forward(アクション名,コントローラ名,モジュール名,パラメータ) | 別のアクションを実行。preDispatch()内でなければ、そのアクションを実行し終えてから新たなアクションの実行へ移る |
_redirect(URL, オプション) | 別のURLにリダイレクトを行う |
_getParam(パラメータ) | リクエストパラメータやURLのパスで指定したパラメータを取得する |
_getAllParams() | すべてのリクエストパラメータを取得する |
_setParam() | リクエストパラメータを設定する |
getRequest() | リクエストオブジェクトを取得する |
getResponse() | レスポンスオブジェクトを取得する |
getInvokeArg(パラメータ) | フロントコントローラから送られたパラメータを取得する |
getInvokeArgs() | フロントコントローラから送られたすべてのパラメータを取得する |
存在しないアクションの呼び出し:__call()
存在しないアクションの呼び出しがあった場合、「__call()
」が呼び出されます。デフォルトでは例外(Zend_Controller_Action_Exception
)をスローしますが、オーバーライドすることでエラーメッセージを表示したりデフォルトのアクションへ転送することができます。エラーコントローラが存在する場合でも__call()
が定義されていればそちらが呼び出されるので、特定のアクションコントローラにのみ__call()
を定義して独自の処理をさせ、後はエラーコントローラに処理を一括させるということも可能です。
public function __call($action, $arg) { $this->view->assign('dt', '指定されたアクションが見つからず、__call()を呼び出しました'); $this->render("index");
上記の例ではメッセージを表示させ、ビューには「index」(index.phtml)を用いています。「$this->render(ビュー)
」で、ビューを指定することが可能です。
「http://localhost/index/wings」へアクセスしてみましょう。次のように_call()
が呼び出されたのが分かります。
今回のまとめ
今回は、Zend Frameworkの中核とも言えるZend_Controllerについて、フロントコントローラとアクションコントローラを中心に解説しました。次回は引き続きZend_Controllerについて、ルーティングやビューとの関連、アクションヘルパーなどを解説していきたいと思います。