ルータ

http://framework.zend.com/manual/ja/zend.controller.router.html#zend.controller.router.usage

しかし、この例では解り辛いのでprojectを作った状態で弄ってみる事とする。

とり急ぎ

zf create project <プロジェクト名>

などでアッサリと雛形を作成し、publicにアクセスすると例のデフォルトの絵が出るかと思われる。

public/.htaccessに以下も追加しておくとよいでしょう

SetEnv APPLICATION_ENV development

例として以下のようにアクセスすると

http://...(/public)/index/test

アクションが見付かりませんといわれてerrorに落ちるはず。その際

Request Parameters:

array (
  'controller' => 'index',
  'action' => 'test',
  'module' => 'default',
)  

と出ているはずだ

で、どこに定義するか

個人的にはBootstrap.phpの中がいいように思いますので、それでやってみます。_initRouteとかでね

基本的な RewriteRouter の操作法、を書いてみる

http://framework.zend.com/manual/ja/zend.controller.router.html#zend.controller.router.usage

application/Bootstrap.php

    protected function _initRoute()
    {
        $this->bootstrap('frontController');
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        $router->addRoute('user',
            new Zend_Controller_Router_Route('user/:username',
                array('controller' => 'user', 'action' => 'info')
            )
        );
 
    }

で、application/views/scripts/index/index.phtmlに、以下のように書いてみると…

<a href="<?php echo $this->url(array('username' => 'martel'), 'user') ?>"><?php echo $this->url(array('username' => 'martel'), 'user') ?></a>

public/user/martel へのリンクになっているのがわかる。アクセスするとuserコントローラなんて知らんと言われるわけだが、パラメータは以下のようになっている事がわかる。

array (
  'username' => 'martel',
  'controller' => 'user',
  'action' => 'info',
)  

つまり

            new Zend_Controller_Router_Route('user/:username',
                array('controller' => 'user', 'action' => 'info')
            )

という定義は、/user/○○が踏まれた時は、userコントローラのinfoアクションに飛ばし、かつその後ろのパラメータを「username」として渡しなさい、という事になるわけだ。

ワイルドカードについて

例えば、先程作成したuserルートより生成されたurlである所の、public/user/martelpublic/user/martel/id/1とかでアクセスすると

array (
  'controller' => 'user',
  'action' => 'martel',
  'id' => '1',
  'module' => 'default',
)

となる。つまりデフォルトルートに落ちてしまっている。というのも今回定義したuserルートは

「'user/:username'」であった為、user/○○と来たものしか掴んでくれないわけ。これの後ろにパラメータを付けたいという場合は、単純にワイルドカード定義すればOK

        $router->addRoute('user',
            new Zend_Controller_Router_Route('user/:username/*', // <- これ
                array('controller' => 'user', 'action' => 'info')
            )
        );

結果

array (
  'username' => 'martel',
  'id' => '1',
  'controller' => 'user',
  'action' => 'info',
)  

デフォルト値について

ところで、/user/martelであるが/userとするとどうなるだろうかというと以下のようにアクセスされてしまう

array (
  'controller' => 'user',
  'action' => 'index',
  'module' => 'default',
)  

つまり、デフォルト行きになったという事。 そうでなく、何かデフォルト値を定義しておけばそちらを見にいってくれたりもする。

        $router->addRoute('user',
            new Zend_Controller_Router_Route('user/:username/*',
                array('controller' => 'user', 'action' => 'info', 'username' => 'alice') // <- aliceをデフォルトに
            )
        );

すると

array (
  'controller' => 'user',
  'action' => 'info',
  'username' => 'alice',
)  

でリクエストされる。いや、何てこともないのだけど一応。

regexルータを利用して拡張子を偽装したりする

例えば、/user/○○.html とかにしたい時とかあるじゃないですか。そういう時にregexルールを使うと。

例えば、現状/user/alice.htmlとかでアクセスすると以下のようにリクエストされる

array (
  'username' => 'alice.html',
  'controller' => 'user',
  'action' => 'info',
)  

というわけでこのように書くぞ、と

    protected function _initRoute()
    {
        $this->bootstrap('frontController');
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        $router->addRoute('user',
            new Zend_Controller_Router_Route_Regex('user/(.+)\.html',
                array('controller' => 'user', 'action' => 'info')
            )
        );
    }

これで/user/alice.htmlでアクセスすると以下のようにリクエストされる

array (
  1 => 'alice',
  'controller' => 'user',
  'action' => 'info',
)  

のであるが、「1」とかになっていて大変渋い上にURLヘルパから値を注入するのが巧く行かなかったりする。従ってこのように改変する。

        $router->addRoute('user',
            new Zend_Controller_Router_Route_Regex('user/(.+)\.html',
                array('controller' => 'user', 'action' => 'info'),
                array('1' => 'user'),
                'user/%s.html'
            )
        );

これで/user/alice.htmlへアクセスすると以下のようにリクエストされる

array (
  'user' => 'alice',
  'controller' => 'user',
  'action' => 'info',
) 

URLヘルパは以下のように記述すればよい

<?php echo $this->url(array('user' => 'bob'), 'user') ?>

拡張子が適当でもアクセスできるようにしたい(同時に拡張子も抜きたい)

alice.htmlでもbob.phpでもいけるように、と。。

これはルートを書くのはそれほど大変な事では無い

        $router->addRoute('user',
            new Zend_Controller_Router_Route_Regex('user/(.+)\.(.+)',
                array('controller' => 'user', 'action' => 'info')
            )
        );

alice.htmlでアクセスすると

array (
  1 => 'alice',
  2 => 'html',
  'controller' => 'user',
  'action' => 'info',
)  

でリクエストされる

以下のようにバインドしておく

        $router->addRoute('user',
            new Zend_Controller_Router_Route_Regex('user/(.+)\.(.+)',
                array('controller' => 'user', 'action' => 'info'),
                array('1' => 'user', 2 => 'ext'),
                'user/%s.%s'
            )
        );

URLヘルパからは以下のように注入しておけばおk

<a href="<?php echo $this->url(array('user' => 'alice', 'ext' => 'html'), 'user') ?>">alice</a>
<a href="<?php echo $this->url(array('user' => 'bob', 'ext' => 'php'), 'user') ?>">bob</a>

configに埋める

http://framework.zend.com/manual/ja/zend.controller.router.html#zend.controller.router.add-config

前回までに定義してきた、user/:username/*をconfigファイルに追い出してみよう。

別ファイルに分けてもいいのだけどどうせなのでapplication/configs/application.iniに書いておく。

[production]
; 略
routes.author.route = "author/:username/*"
routes.author.defaults.controller = user
routes.author.defaults.action = info
routes.author.defaults.username = alice

今回userというルータはregexのために置いておくとして、新たにauthorという名前でルータを定義してみた。 あとはBootstrapでconfigを食わせるだけ。なお、ここで定義したものはオフィシャルにあるように

オプションのキー 'type' を使用すると、 特定のルートで使用するルートクラスの型を指定できます。
デフォルトでは、これは Zend_Controller_Router_Route となります。

という事なので、勝手にRouter_Routeになるという事ですね

application/Bootstrap.php

    protected function _initRoute()
    {
        $this->bootstrap('frontController');
        $front = Zend_Controller_Front::getInstance();
        $router = $front->getRouter();
        $router->addRoute('user',
            new Zend_Controller_Router_Route_Regex('user/(.+)\.(.+)',
                array('controller' => 'user', 'action' => 'info'),
                array('1' => 'user', 2 => 'ext'),
                'user/%s.%s'
            )
        );
 
        $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', 'production');
        $router->addConfig($config, 'routes');
    }

「user」ルートに加えて「author」ルートがconfigから与えられた。 /author/bob/id/2などでアクセスすると以下のようにリクエストされる

array (
  'username' => 'bob',
  'id' => '2',
  'controller' => 'user',
  'action' => 'info',
)  

参考: http://koexuka.blogspot.jp/2010/09/zend-frameworkini.html

ある程度実践例

アプリケーションindexを書き換えたい

/でアクセスされた時において、Indexコントローラとか、indexビューとか、なかなか利用しなかったりするものだったりする、と、いう事もあるだろうと。

たとえば/でアクセスされた時はapplication/controllers/IndexController.phpが呼ばれる事になっているわけだが、これを例えばtestコントローラに飛ばしたいという時どうするか。

zendframework/router.txt · 最終更新: 2012/04/27 19:38 by admin
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0