SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Zend Framework入門

Zend Framework入門(3):PHPでMVCアプリケーションを構築しよう - Zend_Controller(前編) -

Zend Frameworkによる実践的なPHPアプリケーション開発 3

  • X ポスト
  • このエントリーをはてなブックマークに追加

アクションコントローラ

 フロントコントローラにおいてディスパッチされたリクエストを実際に処理するのが、アクションコントローラです。

 例えばリクエストが「Codezine」コントローラの「display」アクションを要求している場合、通常ディスパッチの過程でコールされるのは、アクションコントローラにおける「CodezineController」クラスの「displayAction()」メソッドです(命名規則については前回を参照)。

Zend_Controller_Actionのサブクラスの作成/アクションメソッドの記述

 アクションコントローラを使用するには、まずZend_Controller_Actionのサブクラスを作成するところから始まります。そしてサブクラスの中に最低一つ、アクションメソッドを用意する必要があります。前回触れたとおり、「IndexController」「indexAction()」はそれぞれデフォルトのクラス/アクションメソッドです(前出のサンプルのように、名前は変更することができます)。

 またアクションコントローラ内には、アクションメソッド以外にもいくつかの特定の役割を持つメソッドを定義することができます。以下具体的に、メソッド(init()preDispatch()postDispatch())を解説していきます。これらのメソッドは、以下の順で実行されます。

  1. init()
  2. preDispatch()
  3. (アクションメソッド)
  4. postDispatch()

アクションコントローラの初期化処理:init()

 アクションコントローラにおいて何か特別な初期化作業を行いたい場合はinit()メソッドを用います。これはアクションコントローラのコンストラクタの最後に呼び出されるものです。

init() (IndexController.php 抜粋)
class IndexController extends Zend_Controller_Action
{
    public function init()
    {
(初期化処理)
    }
:
:

ディスパッチ前後に行う処理:preDispatch()/postDispatch()

 ディスパッチ処理の前後に、特定の処理を行うようにすることができます。例えば認証情報チェックやビューの仕上げの処理などです。これはリクエストされたアクション・メソッドの実行前後にそれぞれpreDispatch()postDispatch()がコールされることで実現されます。この2つのメソッドに行いたい処理を記述します。

 先ほどディスパッチの項で触れたフラグのリセットもここで可能です。それにより処理先のコントローラやアクション、パラメータを変更してリクエストを再度処理することが可能になります。それを実現するのが「_forward()」メソッドです。以下に概要を示しておきます。_forward(アクション名,コントローラ名,モジュール名,パラメータ)とすることで別のアクションの実行に移ります(もしアクションメソッド内でコールされれば、現在のアクションを実行し終えてから新たなアクションの実行へ移ります)。

 preDispatch()init()もアクションメソッドに先立って実行されますが、preDispatch()init()の後に実行されます。

サンプル

 以下にinit()preDispatch()_forward()を利用したサンプルを示します。

InitsampleController.php
<?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通りの時間帯にアクセスした結果を示します。

9時~17時にアクセスした場合
9時~17時にアクセスした場合
時間外にアクセスするとindexコントローラのindexアクションへ
時間外にアクセスするとindexコントローラのindexアクションへ

エラーコントローラ

 前回少し触れましたが、デフォルトでは「ErrorHandler」プラグインが有効になっています。「ErrorHandler」プラグインは、指定されたアクションコントローラやアクションメソッドが見つからない時(404型エラー)や、それ以外にアクションコントローラ内で例外(500型エラー)が発生した時にエラーを処理するためのプラグインです。このプラグインを使用するには、以下のファイルを用意します。

エラーハンドラプラグインで用意するもの
ファイル説明
application/controllers/ErrorController.phpエラーコントローラファイル
application/views/scripts/error/error.phtmlエラーコントローラ用ビューファイル(ViewRendererが有効な場合)

 エラーコントローラファイルには、errorアクションメソッドを用意します。

ErrorController.php
<?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」です。以下の例では取得したエラーの型を表示しています。

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()については先ほどサンプルでも使いました。

Zend_Controller_Actionメソッド
メソッド内容
_forward(アクション名,コントローラ名,モジュール名,パラメータ)別のアクションを実行。preDispatch()内でなければ、そのアクションを実行し終えてから新たなアクションの実行へ移る
_redirect(URL, オプション)別のURLにリダイレクトを行う
_getParam(パラメータ)リクエストパラメータやURLのパスで指定したパラメータを取得する
_getAllParams()すべてのリクエストパラメータを取得する
_setParam()リクエストパラメータを設定する
getRequest()リクエストオブジェクトを取得する
getResponse()レスポンスオブジェクトを取得する
getInvokeArg(パラメータ)フロントコントローラから送られたパラメータを取得する
getInvokeArgs()フロントコントローラから送られたすべてのパラメータを取得する

存在しないアクションの呼び出し:__call()

 存在しないアクションの呼び出しがあった場合、「__call()」が呼び出されます。デフォルトでは例外(Zend_Controller_Action_Exception)をスローしますが、オーバーライドすることでエラーメッセージを表示したりデフォルトのアクションへ転送することができます。エラーコントローラが存在する場合でも__call()が定義されていればそちらが呼び出されるので、特定のアクションコントローラにのみ__call()を定義して独自の処理をさせ、後はエラーコントローラに処理を一括させるということも可能です。

IndexController.php(抜粋)
public function __call($action, $arg)
{
    $this->view->assign('dt',
        '指定されたアクションが見つからず、__call()を呼び出しました');
    $this->render("index");

 上記の例ではメッセージを表示させ、ビューには「index」(index.phtml)を用いています。「$this->render(ビュー)」で、ビューを指定することが可能です。

 「http://localhost/index/wings」へアクセスしてみましょう。次のように_call()が呼び出されたのが分かります。

__call()が呼び出された画面
__call()が呼び出された画面

今回のまとめ

 今回は、Zend Frameworkの中核とも言えるZend_Controllerについて、フロントコントローラとアクションコントローラを中心に解説しました。次回は引き続きZend_Controllerについて、ルーティングやビューとの関連、アクションヘルパーなどを解説していきたいと思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Zend Framework入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 川北 季(カワキタ ミノル)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2162 2008/02/19 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング