前回投稿したZend Frameworkを使ったサンプルで、例外関連の設定を試します。
エラーハンドラプラグインは、デフォルトの状態です。

次のようにアクションコントローラ内で例外をスローすると、「Zend Framework:Hello Worldを表示してみる」で作成したエラーページが表示されます。

BASEDIR/webapp03/modules/default/controllers/IndexController.php
PHP:
  1. class IndexController extends Tz_Controller_Action
  2. {
  3.   // 略
  4.  
  5.   public function throwAction()
  6.   {
  7.     throw new Exception('throwActionでスローします。');
  8.   }
  9.   // 略
  10. }

以下、マニュアルにある方法の一部を試します。

独自の例外処理

エラーハンドラプラグインで例外を処理しない設定を試します。
フロントコントローラのthrowExceptionsを有効にすると、デフォルトのエラーページは表示されなくなります。

BASEDIR/webapp03/bootstrap.php
PHP:
  1. function bootstrap($webapp_dir)
  2. {
  3.   // 2009/02/09 追加
  4.   if (!class_exists('Zend_Controller_Action',false)) {
  5.     require_once 'Zend/Controller/Action.php';
  6.   }
  7.  
  8.   // 略
  9.  
  10.   //require 'Zend/Controller/Front.php';// 2009/02/09 コメントアウト
  11.   $front = Zend_Controller_Front::getInstance();
  12.  
  13.   $modules_dir = $webapp_dir . '/modules';
  14.  
  15.   $ctrl_dirs = array(
  16.                      'default' => $modules_dir . '/default/controllers',
  17.                      );
  18.   $front->setControllerDirectory($ctrl_dirs);
  19.  
  20.   require_once $webapp_dir . '/MyAppPlugin.php';
  21.   $front->registerPlugin(new MyAppPlugin());
  22.  
  23.   require_once $webapp_dir . '/lib/Tz/Controller/Action.php';
  24.  
  25.   $front->throwExceptions(true);
  26.  
  27.   try {
  28.     $front->dispatch();
  29.   }
  30.   catch (Exception $exception) {
  31.     //v($exception->getMessage());
  32.     $content = '<html><head>';
  33.     $content .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
  34.     $content .= '<title>エラー</title>';
  35.     $content .= '</head><body>';
  36.     $content .= 'エラーが発生しました.';
  37.     $content .= '</body></html>';
  38.     echo $content;
  39.   }
  40. }

アクションコントローラ内で例外をスローすると、上記コードの32行目が実行されます。

例外時はデフォルトのコントローラとアクションを使用する

アクションコントローラで例外が発生した場合、デフォルトのコントローラとアクションを使用したページを表示するには、フロントコントローラのパラメータのuseDefaultControllerAlwaysをtrueに設定します。

PHP:
  1. $front->setParam('useDefaultControllerAlways', true);

この設定を行うとディスパッチャは例外をスローしないという記述がマニュアルにあります。
例外がスローされるほとんどの状況で、常にデフォルトのページが表示されることになります。

useDefaultControllerAlwaysとthrowExceptionsを同時に設定した場合は、throwExceptionsの設定は無視されるようです。

PHP:
  1. $front->setParam('useDefaultControllerAlways', true);
  2. $front->throwExceptions(true);

アクションが存在しない時、デフォルトのアクションを使用する

コントローラ内で、アクションが存在しなかった場合、特定のページを表示するようにしてみます。

BASEDIR/webapp03/modules/default/controllers/CallController.php
PHP:
  1. class CallController extends Tz_Controller_Action
  2. {
  3.   public function indexAction()
  4.   {
  5.     $this->view->testMsg = "テストメッセージです。" . $this->getRequest()->getControllerName();
  6.   }
  7.  
  8.   public function __call($method, $args)
  9.   {
  10.     if ('Action' == substr($method, -6)) {
  11.       return $this->_redirect('/' . $this->getRequest()->getControllerName());
  12.     }
  13.     throw new Exception('Invalid method');
  14.   }
  15. }

Callコントローラに存在しないアクションを指定すると、Callコントローラのindexアクションで処理されるページが表示されます。
存在するアクション内で例外をスローした場合は、__callメソッドは起動されませんので、エラーハンドラプラグイン等で処理することになります。

メモ

例外処理(エラーページの表示等)は、デフォルトのエラーハンドラプラグインで処理しようと思います。

  • useDefaultControllerAlwaysは、たぶん今後使用しないので忘れる。
  • throwExceptionsを有効にする方法は、使用する機会はないと思う。
  • __callメソッドをオーバーライドする方法は、いつでも使えるように忘れない。

サンプルダウンロード

ダウンロードページにアーカイブしたファイルを置きました。

追記 2009/02/09

このページのサンプルは、Zend Framework 1.5.2を使用していました。
いつ頃からか、インクルードするZend Frameworkのライブラリが足りず、エラーがでるようになりました。

修正方法です。

1.

bootstrap.phpで定義したbootstrap()関数の最初に次のようなものを追加します。

PHP:
  1. if (!class_exists('Zend_Controller_Action',false)) {
  2.     require_once 'Zend/Controller/Action.php';
  3.   }

2.

次に、bootstrap.phpに定義したbootstrap()関数内の require 'Zend/Controller/Front.php'; をコメントアウトします。

PHP:
  1. //require 'Zend/Controller/Front.php';

以上で、Zend Framework 1.7.3では、必要なクラスをインクルードでき、「Fatal error: Class 'Zend_Controller_Action' not found 」というエラーがなくなります。

Tags:

コメントをどうぞ