ルーティング

Fuel では、単純な静的なルート設定から HTTP の動詞によるルーティングを用いた高度なルート設定に至るまで、様々なルーティングが可能です。

ルート設定は、fuel/app/config/routes.php で行います。

予約済みルート

Fuel では次の4つの予約済みルート設定があります。_root_, _403_, _404_, _500_.

リクエストした URI (ルーティング)がアプリケーション内で解決できないとき、 request クラスが HttpNotFoundException を投げます。

_404_ ルートが未定義の場合、フレームワーク自身のエラーハンドラを使って "page not found" メッセージが表示されます。 _403_ または _500_ ルートが未定義の場合、 これらの例外はキャッチされないまま、あなたのアプリケーションが投げる他の例外と同様に処理されます。

return array(
    '_root_'  => 'welcome/index',
    '_404_'   => 'welcome/404',
);

基本的なルーティング

左辺に記述されたルートは、リクエストされた URI と比較されます。もし一致していれば、そのリクエストは右辺の URI に経路づけられます。

このルーティングによって、次のようなことが可能になります。:

return array(
    'about'   => 'site/about',
    'contact' => 'contact/form',
    'admin'   => 'admin/login',
);

やや高度なルーティング

ルート設定には正規表現を含めることが出来ます。 左辺とリクエストされた URI が一致したら、その一致した部分を右辺に代入するといったような、 左辺の正規表現による右辺の後方参照が利用可能です。また、次のようないくつかの特別な宣言があり、それを用いて何かに一致させたり、 あるいは特定セグメントに一致させたりすることが出来ます。

ここにいくつかの例があります。 :any:everything の間の微妙な違いに注意:

return array(
    'blog/(:any)'       => 'blog/entry/$1', // /blog/entry_name が /blog/entry/entry_name に経路付けられ、
                                            //   /blog/ と一致します。 /blogging や /blog とは一致しません。
    'blog(:any)'        => 'blog/entry$1',  // /blog/entry_name が /blog/entry/entry_name に経路付けられ、
                                            //   /blog/ や /blogging と一致します。 /blog とは一致しません。
    'blog(:everything)' => 'blog/entry$1',  // /blog/entry_name が /blog/entry/entry_name に経路付けられ、
                                            //   /blog/ 、 /blogging や /blog と一致します。
    '(:segment)/about'  => 'site/about/$1', // /en/about が /site/about/en に経路付けられる
    '(\d{2})/about'     => 'site/about/$1', // /12/about が /site/about/12 に経路付けられる
);

高度なルーティング

ルート設定では、名前付きパラメータを使えます。これより、URI セグメントに対して名前を与えることができ、 アクションメソッドの中でアクセスできます。

例:

return array(
    'blog/:year/:month/:id' => 'blog/entry', // /blog/2010/11/entry_name が /blog/entry に経路付けられる
);

上の例では、/blog/2010/11/entry_name が捕捉され、 'blog' コントローラ内の 'entry' アクションにルーティングされます。 そこでは、下記のような名前付きパラメータを使うことができます。:

$this->param('year');
$this->param('month');
$this->param('id');

名前付きパラメータは正規表現で、後方参照として数えられることに注意しましょう。 例えば ':name/(\d{2})' において、2 桁の数字への後方参照は $2 であって、$1 ではありません。

HTTP の動詞によるルーティング

アクセスされた HTTP の動詞に基づいて、URL をコントローラとアクションに経路付けることができます。 このことによって、素早く簡単に RESTful なコントローラを作成できます。

例:

return array(
    // GET /blog が /blog/all に、POST /blog が /blog/create に経路付けられる
    'blog' => array(array('GET', new Route('blog/all')), array('POST', new Route('blog/create'))),
);

URL には、名前付きパラメータと正規表現を普通に使えます:

return array(
    'blog/(:any)' => array(array('GET', new Route('blog/show/$1'))),
);

3 つめパラメータに false あるいは true を渡すことで、ルートが HTTP のみをサポートするのか、あるいは HTTPS のみをサポートするのかを指定することもできます。

// HTTPS のリクエストであった場合のみルートが有効になります
return array(
    'blog/(:any)' => array(array('GET', new Route('blog/show/$1'), true)),
);

名前付きルートとリバースルーティング

リバースルーティングというのは、次のような考え方を指します。たとえば管理エリアを作ろうとし、そのルートをセットアップします。 ビューにおいて、管理エリアで例えば 'admin/start/overview' という HTML アンカーを使いたいとしましょう。 ところが、気が変わって、そのページを 'admin/overview' という風に変えることにします。 その結果、全てのビューで、そのリンクを更新しなければならなくなってしまいました...

名前付きルートとリバースルーティングを用いると、名前付きルートをアンカーリンクにすることができ、 ルートが変わっても、各ビューの中でのリンクはその変更を自動的に追随します。

ルートの例:

return array(
    'admin/start/overview' => array('admin/overview', 'name' => 'admin_overview'), // admin/overview ページに対して名前付きルート名を追加する
);

アンカーの例:

// <a href="http://your_base_url/admin/start/overview">Overview</a> を生成する
echo Html::anchor(Router::get('admin_overview'), 'Overview');

今のところ、 app/config/routes.php に定義されているルートのみで動作することに注意しましょう。モジュールのルートでは動作しません。

インラインルート

ルートはコントローラのメソッドに解決される必要はありません。 FuelPHP はコントローラメソッドを置き換える Closure として定義される インラインルートもサポートします。コントローラのメソッドと同様にインラインルートは Response オブジェクト を返さなければなりません。 この Response オブジェクトは 自分で forge するか、 forge された Request を実行した結果として返します。

ルートの例:

return array(
    'secret/mystuff' => function () {
		// このルートは development 環境でのみ動作します
		if (\Fuel::$env == \Fuel::DEVELOPMENT)
		{
			return \Request::forge('secret/mystuff/keepout', false)->execute();
		}
		else
		{
			throw new HttpNotFoundException('This page is only accessable in development.');
		}
};

モジュールとルーティング

モジュールがどのようにルーティングを扱うか をお読みください。