[Zend Framework] Zend_Controller: ルーティングを変更して、任意のURIでアクセスできるようにする(1)

URIの変更を行う場合に必要なルーティング設定に関して確認します。
Zend_Controller_Router_Route_Static
Zend Framework Version: 1.12.3

参考サイト

標準では、リクエストのあったURIを下記のように解釈して、実行します。

http://[host]/[Controller]/[action]/

何らかの理由でこれを変更したい場合に、下記を使ってルーティングを変更します。

Rewrite ルータには、6 種類の基本的なルーティング方式があります (そのうちのひとつは特別なものです)。

  • Zend_Controller_Router_Route
  • Zend_Controller_Router_Route_Static
  • Zend_Controller_Router_Route_Regex
  • Zend_Controller_Router_Route_Hostname
  • Zend_Controller_Router_Route_Chain
  • Zend_Controller_Router_Rewrite *

通常、下記のようなURIでビューを表示させる場合、Sitemapコントローラを作ることになります。

http://sample.dev:10088/sitemap

コントローラを別に作るほどの処理がないので、ルーティングを変更してIndexコントローラでまかなってみます。

Contents

Index コントローラにアクションを追加する

zf で sitemap という action を作成します。

% zf.sh create action sitemap Index
Note: PHPUnit is required in order to generate controller test stubs.
Creating an action named sitemap inside controller at /Users/***/projects/sample/application/controllers/IndexController.php
Updating project profile '/Users/***/projects/sample/.zfproject.xml'
Creating a view script for the sitemap action method at /Users/***/projects/sample/application/views/scripts/index/sitemap.phtml
Updating project profile '/Users/***/projects/sample/.zfproject.xml'

現在は下記にアクセスすると、ビューが表示されます。

http://sample.dev:10088/index/sitemap

変更予定のURIを見てみます。

http://sample.dev:10088/sitemap

.htaccess やバーチャルホストの設定に下記が追記されていると、エラーが表示されます。

SetEnv APPLICATION_ENV development
Request Parameters:
array (
  'controller' => 'sitemap',
  'action' => 'index',
  'module' => 'default',
)

Zend_Controller_Router_Route_Static

設定は下記のどちらかになります。

  • Bootstrap.php に設定する
  • application.ini などのconfig ファイルに追い出す

Bootstrap.php

application/Bootstrap.php
    protected function _initRoute()
    {
        // ルータオブジェクトを取得
        $this->bootstrap('frontController');
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        // ルーティング設定
        $route = new Zend_Controller_Router_Route_Static(
            'sitemap',
            array(
                'module'     => 'default',
                'controller' => 'index',
                'action'     => 'sitemap'
            )
        );
        // 設定追加
        $router->addRoute('sitemapRoute', $route);
    }

application.ini

上記の公式では INI ファイルを、Zend_Config オブジェクトに読み込んでいますが、下記のように設定すれば不要なようです。

application/configs/application.ini
; +--------+
; | Router |
; +--------+
; resources.router.routes.sitemap.type = "Zend_Controller_Router_Route_Static"
resources.router.routes.sitemap.route = "sitemap"
resources.router.routes.sitemap.defaults.module = "default"
resources.router.routes.sitemap.defaults.controller = "index"
resources.router.routes.sitemap.defaults.action = "sitemap"

補遺

どのようなときにそれぞれの機能を利用するかちょっと検討してみます。
moduleもからむとURIをコントロールする必要がさらに高まるように思えるので、ある程度の規模を持つサイト構築では必須な気がします。

Rewrite ルータには、6 種類の基本的なルーティング方式があります (そのうちのひとつは特別なものです)。

Zend_Controller_Router_Route

フレームワークの標準のルーティングとのこと。
http://[host]/[Controller]/[action]/[引数] のようなURIを分かりやすい形式に整える時などに使うのかな。

http://domain.com/archive/read/2005
=> http://domain.com/archive/2005

Zend_Controller_Router_Route_Static

今回調べたもの。例えば login / logout のようなURIを作るときに利用されそう。

http://domain.com/auth/login
=> http://domain.com/login

Zend_Controller_Router_Route_Regex

正規表現によるルーティング。
「他のものに比べてより強力で柔軟なものですが、 多少複雑になってしまいます。そして、より高速になります。」とのこと。
拡張子の偽装に利用されている方もいました。

Zend_Controller_Router_Route_Hostname

「標準のルートと同じように動作しますが、 パスではなくコールされた URL のホスト名に基づいて動作します。」とのこと。
こちらは、呼ばれるホストによって、モジュールを変えているようです。

Zend_Controller_Router_Route_Chain

「複数のルートを一緒にチェーンできるルートです。 これは、たとえばホスト名とルート、パスとルート、または複数のパスとルートをチェーンできます。」とのこと。
どのように使うと良いのか、まだ分かっていません。

Zend_Controller_Router_Rewrite *

Zend_Controller_Router_Route と同じなのか、ちがうのか。

Zend_Rest_Route

6種類に含まれていなかったのですが、勝手に追加。
「Zend_Restコンポーネントは、 Zend_Controller_Router_RewriteのためにRESTfulなルートを含みます。 このルートは、HTTPメソッド及びURIをモジュール、 コントローラ及びアクションに変換することにより、 リクエストを割り振る標準化されたルーティング機構を提供します。」とのこと。
RESTful といえば Rails なので、Zend_Controller_Router_Route の代わりに Zend_Rest_Route を使うと Rails 風に振る舞ってくれるということのようですと勝手に解釈しましたがいろいろ違うと思います。

利用している方がいました。