Zend_Controller_Router_Route(日本語)
Zend_Controller_Router_Route はフレームワークの標準のルートです。
簡単に利用でき、柔軟なルート定義が可能です。各ルートには、まず
(静的および動的な) URL のマッピングが含まれ、
そしてデフォルト値および変数についての制限を指定して初期化します。
とある架空のアプリケーションで、コンテンツの作者情報のページが必要になったとしましょう。
ブラウザで http://domain.com/author/martel
にアクセスした際に、"martel" とかいう人についての情報を見たいわけです。
この機能を実現するためのルートは、次のようになります。
'profile',
'action' => 'userinfo'
)
);
$router->addRoute('user', $route);
]]>
Zend_Controller_Router_Route
のコンストラクタの最初のパラメータは、ルートの定義です。
これを URL にマッチさせます。ルート定義は静的な部分と動的な部分で構成され、
それをスラッシュ ('/') で連結します。
静的な部分は単なるテキスト (例. author) です。
動的な部分を変数と呼び、変数名の前にコロンをつけて
(例. :username) 表します。
文字の使用法
現在の実装では、(スラッシュ以外の)
任意の文字を変数名として使用できます。しかし、
PHP の変数名として使用できる文字だけを用いることを強く推奨します。
このようにしておくことで、
将来実装が変更されたときにバグを引き起こす可能性を抑えられます。
この例のルートは、ブラウザで
'http://domain.com/author/martel' を指した際にマッチします。
この場合、すべての変数の値が Zend_Controller_Request
オブジェクトに注入され、ProfileController からアクセスできるようになります。
この例が返す変数は、以下のようなキーと値のペアを持つ配列となります。
'martel',
'controller' => 'profile',
'action' => 'userinfo'
);
]]>
その後、Zend_Controller_Dispatcher は
(デフォルトモジュールの) ProfileController クラスにある
userinfoAction() メソッドを実行します。変数にアクセスするには、
Zend_Controller_Action::_getParam() あるいは
Zend_Controller_Request::getParam() メソッドを使用します。
getRequest();
$username = $request->getParam('username');
$username = $this->_getParam('username');
}
]]>
ルート定義には、特殊文字 (ワイルドカード)
を含めることができます。これは '*' 記号で表します。
これを使用して、Module ルートと同様にパラメータを扱う
(変数名 => 値 のペアを URI で定義する) ことができます。
次のルートは、Module ルートの挙動をまねたものです。
'default')
);
$router->addRoute('default', $route);
]]>
変数のデフォルト
ルートで使用するすべての変数についてデフォルト値を指定できます。
これは、 Zend_Controller_Router_Route
のコンストラクタの 2 番目のパラメータで指定します。
このパラメータは、変数名をキーとする配列で、
対応する値にそのデフォルト値を指定します。
2006)
);
$router->addRoute('archive', $route);
]]>
上のルートは 'http://domain.com/archive/2005' および
'http://example.com/archive'
のような URL にマッチします。後者の場合、変数 year にはデフォルト値である
2006 が設定されます。
この例は、year 変数をリクエストオブジェクトに注入することになります。
そしてルーティング情報が存在しない
(コントローラやアクションのパラメータが定義されていない) ので、
アプリケーションはデフォルトのコントローラのデフォルトアクションメソッド
(ともに Zend_Controller_Dispatcher_Abstract で定義されています)
にディスパッチします。より使いやすくするには、
ルートのデフォルトとしてコントローラとアクションを定義しておく必要があります。
2006,
'controller' => 'archive',
'action' => 'show'
)
);
$router->addRoute('archive', $route);
]]>
このルートは、ArchiveController の
showAction() を実行します。
変数の制約
Zend_Controller_Router_Route のコンストラクタの
三番目のパラメータで、変数の制約を指定できます。
これは、正規表現で指定します。
2006,
'controller' => 'archive',
'action' => 'show'
),
array('year' => '\d+')
);
$router->addRoute('archive', $route);
]]>
上の例のルートでは、year 変数の値が数値データである場合にのみ
Rewrite ルータにマッチします。つまり
http://domain.com/archive/2345 はマッチしますが
http://example.com/archive/test はマッチしません。
この場合はチェイン内の次のルートに処理を移します。
翻訳済みセグメント
標準のルートは、翻訳済みセグメントをサポートします。この機能を使用するには、
次のいずれかの方法で翻訳器 (Zend_Translate のインスタンス)
を定義しなければなりません。
レジストリに、キー Zend_Translate で格納する
静的メソッド
Zend_Controller_Router_Route::setDefaultTranslator() で設定する
コンストラクタの 4 番目のパラメータとして渡す
デフォルトでは、Zend_Translate
のインスタンスで指定したロケールを使用します。これを上書きするには、
(Zend_Locale のインスタンスあるいはロケール文字列で)
次のいずれかの方法で設定します。
レジストリに、キー Zend_Locale で格納する
静的メソッド
Zend_Controller_Router_Route::setDefaultLocale() で設定する
コンストラクタの 5 番目のパラメータとして渡す
アセンブルメソッドのパラメータ @locale として渡す
翻訳済みセグメントはふたつの部分に分かれます。
固定セグメントの前には @ 記号がひとつつき、
アセンブル時に現在のロケールに翻訳され、
マッチングの際にはメッセージ ID に戻されます。
動的セグメントの前には :@ がつきます。
アセンブルの際に、指定したパラメータが翻訳され、
パラメータの位置に挿入されます。
マッチングの際には、URL の翻訳済みパラメータが
メッセージ ID に戻されます。
メッセージ ID と分割された言語ファイル
ルートの中で使いたいメッセージ ID が、
ビュースクリプトやその他の部分ですでに使われていることもあるでしょう。
URL の安全性を確保するには、
ルートで使用するメッセージを別の言語ファイルに分割しなければなりません。
標準のルートで翻訳済みセグメントを使用するための準備として
もっともシンプルな方法は、次のようになります。
'array',
'content' => array(),
'locale' => 'en'
)
);
$translator->addTranslation(
array(
'content' =>
array(
'archive' => 'archiv',
'year' => 'jahr',
'month' => 'monat',
'index' => 'uebersicht'
),
'locale' => 'de'
)
);
// 現在のロケールを翻訳器に設定します
$translator->setLocale('en');
// ルートのデフォルト翻訳器として設定します
Zend_Controller_Router_Route::setDefaultTranslator($translator);
]]>
これは、静的セグメントを使用する例です。
'archive',
'action' => 'index'
)
);
$router->addRoute('archive', $route);
// URL をデフォルトのロケールでアセンブルします: archive
$route->assemble(array());
// URL をドイツ語でアセンブルします: archiv
$route->assemble(array());
]]>
動的セグメントを使用すると、
モジュールルートの翻訳済みバージョンを作ることができます。
'index',
'action' => 'index'
)
);
$router->addRoute('archive', $route);
// URL をデフォルトのロケールでアセンブルします: archive/index/foo/bar
$route->assemble(array('controller' => 'archive', 'foo' => 'bar'));
// URL をドイツ語でアセンブルします: archiv/uebersicht/foo/bar
$route->assemble(array('controller' => 'archive', 'foo' => 'bar'));
]]>
静的セグメントと動的セグメントを同時に使用することもできます。
'year'
'value' => 2005,
'controller' => 'archive',
'action' => 'show'
),
array('mode' => '(month|year)'
'value' => '\d+')
);
$router->addRoute('archive', $route);
// URL をデフォルトのロケールでアセンブルします: archive/month/5
$route->assemble(array('mode' => 'month', 'value' => '5'));
// URL をドイツ語でアセンブルします: archiv/monat/5
$route->assemble(array('mode' => 'month', 'value' => '5', '@locale' => 'de'));
]]>