Zend_Controller_Router_Route_Regex(日本語)
デフォルトのルートや静的なルートに加えて、正規表現によるルートも使用可能です。
このルートは他のものに比べてより強力で柔軟なものですが、
多少複雑になってしまいます。そして、より高速になります。
標準のルートと同様、このルートを初期化する際にはルートの定義とデフォルトを指定する必要があります。
サンプルとして、archive ルートを作成してみましょう。
これは先ほど定義したものとほぼ同じですが、今回は Regex ルートを使用しています。
'archive',
'action' => 'show'
)
);
$router->addRoute('archive', $route);
]]>
定義された正規表現のパターンが、リクエストオブジェクトに注入されます。
上の例では、http://domain.com/archive/2006
がマッチした後の結果の値は次のような配列になります。
'2006',
'controller' => 'archive',
'action' => 'show'
);
]]>
ルータとのマッチングを行う前に、URL の先頭と最後のスラッシュは取り除かれます。
結果として、URL http://domain.com/foo/bar/
は正規表現 foo/bar にマッチすることになります。
/foo/bar にはマッチしません。
行頭と行末を表す文字 (それぞれ '^' および '$')
が、すべての式の前後に自動的に付加されます。
したがって、これらは正規表現で指定する必要はありません。
このルートクラスは、区切り文字として '#' を使用します。
つまり、ルート定義の中にハッシュ文字 ('#')
がある場合は、それをエスケープする必要があるということです。
スラッシュ ('/') をエスケープする必要はありません。
'#' (アンカー) は通常はウェブサーバに渡されることはないので、
エスケープが必要になることはまずないでしょう。
定義されたサブパターンの内容は、通常通りの方法で取得できます。
getRequest();
$year = $request->getParam(1); // $year = '2006';
}
]]>
このキーは、文字列 ('1') ではなく数値の 1 であることに注意しましょう。
このルートは、標準のルートとまったく同様に動作するわけではありません。
'year' のデフォルトが設定されていないからです。
また、year のデフォルトを設定してこれをオプション扱いにしたとしても、
最後のスラッシュをどうするかという問題が残ります。
これを解決するには、year 部をスラッシュを含めてオプションにし、
その数値部のみを取得するようにします。
'2006',
'controller' => 'archive',
'action' => 'show'
)
);
$router->addRoute('archive', $route);
]]>
まだ問題が残っていることにおそらくお気づきでしょう。
パラメータとして数値のキーを使用するのはなかなか難しく、
長い目で見れば問題を引き起こす可能性が高くなります。
そこで三番目のパラメータの登場です。
このパラメータは、正規表現サブパターンとパラメータ名のキーを関連付けます。
簡単な例を見てみましょう。
'archive',
'action' => 'show'
),
array(
1 => 'year'
)
);
$router->addRoute('archive', $route);
]]>
この結果は次のようになり、これがリクエストオブジェクトに格納されます。
'2006',
'controller' => 'archive',
'action' => 'show'
);
]]>
関連付けは両方の方法で定義でき、任意の環境 (例. Zend_Config) で動作します。
キーには変数名あるいはサブパターン番号のいずれかを含めることができます。
'year')
);
// あるいは
$route = new Zend_Controller_Router_Route_Regex(
'archive/(\d+)',
array( ... ),
array('year' => 1)
);
]]>
サブパターンのキーは整数値でなければなりません。
リクエストの値から数値キーが消え、代わりに名前がつけられたことに注目しましょう。
もちろん、お望みなら数値での指定と名前での指定を共用することもできます。
1)
);
]]>
この結果、リクエスト内には数値キーと名前つきキーが共存することになります。
たとえば、URL http://domain.com/archive/2006/page/10
は次のような値になります。
'2006',
2 => 10,
'controller' => 'archive',
'action' => 'show'
);
]]>
正規表現を簡単に反転させることはできないので、
URL ヘルパーやこのクラスのメソッドを使用するには
逆の URL を準備しておく必要があります。
逆方向のパスは sprintf() 形式の文字列で表し、
コンストラクタの四番目のパラメータとして指定します。
1),
'archive/%s'
);
]]>
これまで説明してきたことは、すべて標準のルートオブジェクトでも可能なことです。
それでは、Regex ルートを使用するメリットはいったい何なのでしょう?
これを使用すると、あらゆる形式の URL を制約なしに定義することができます。
仮に、あなたが blog を持っており
http://domain.com/blog/archive/01-Using_the_Regex_Router.html
のような URL を作成したいと考えたとしましょう。
このパスの最後の要素 01-Using_the_Regex_Router.html
から記事の ID とタイトル/説明 を取得するにはどうしたらいいでしょうか?
標準のルートでは不可能でしょう。Regex ルートを使用した場合は、
次のようにすることができます。
'blog',
'action' => 'view'
),
array(
1 => 'id',
2 => 'description'
),
'blog/archive/%d-%s.html'
);
$router->addRoute('blogArchive', $route);
]]>
regex ルートは標準のルートよりはるかに柔軟性があるということが、
ここからもわかります。