URIルーティング
URIルーティングとは?
URIルーティングは、URIをコントローラーのメソッドに関連付けます。
CodeIgniterには、2種類のルーティングがあります。1つは定義済みルートルーティング、もう1つは自動ルーティングです。定義済みルートルーティングでは、ルートを手動で定義できます。柔軟なURLが可能です。自動ルーティングは、規約に基づいてHTTPリクエストを自動的にルーティングし、対応するコントローラーメソッドを実行します。ルートを手動で定義する必要はありません。
まず、定義済みルートルーティングを見てみましょう。自動ルーティングを使用する場合は、自動ルーティング(改良版)を参照してください。
ルーティングルールの設定
ルーティングルールは、**app/Config/Routes.php**ファイルで定義されます。このファイルには、RouteCollectionクラス($routes
)のインスタンスを作成し、独自のルーティング条件を指定できるようにすることが示されています。ルートは、プレースホルダーまたは正規表現を使用して指定できます。
ルートを指定するときは、HTTP動詞(リクエストメソッド)に対応するメソッドを選択します。GETリクエストを期待する場合は、get()
メソッドを使用します。
<?php
$routes->get('/', 'Home::index');
ルートは、左側に**ルートパス**(BaseURLからの相対URIパス。/
)を取り、右側に**ルートハンドラー**(コントローラーとメソッドHome::index
)と、コントローラーに渡す必要のあるパラメーターをマップします。
コントローラーとメソッドは、Users::list
のように、クラスとそのメソッドをダブルコロンで区切って、静的メソッドを使用する場合と同じようにリストする必要があります。
そのメソッドにパラメーターを渡す必要がある場合は、メソッド名の後にスラッシュで区切ってリストします。
<?php
// Calls $Users->list()
$routes->get('users', 'Users::list');
// Calls $Users->list(1, 23)
$routes->get('users/1/23', 'Users::list/1/23');
例
以下に、いくつかの基本的なルーティングの例を示します。
最初のセグメントに**journals**という単語を含むURLは、\App\Controllers\Blogs
クラスと、通常はindex()
であるデフォルトメソッドにマップされます。
<?php
$routes->get('journals', 'Blogs');
**blog/joe**というセグメントを含むURLは、\App\Controllers\Blogs
クラスとusers()
メソッドにマップされます。IDは34
に設定されます。
<?php
$routes->get('blog/joe', 'Blogs::users/34');
最初のセグメントが**product**で、2番目のセグメントに何かがあるURLは、\App\Controllers\Catalog
クラスとproductLookup()
メソッドにマップされます。
<?php
$routes->get('product/(:segment)', 'Catalog::productLookup');
最初のセグメントが**product**で、2番目のセグメントが数値のURLは、\App\Controllers\Catalog
クラスとproductLookupByID()
メソッドにマップされ、一致したものがメソッドに変数として渡されます。
<?php
$routes->get('product/(:num)', 'Catalog::productLookupByID/$1');
HTTP動詞ルート
標準のHTTP動詞(GET、POST、PUT、DELETE、OPTIONSなど)を使用できます。
<?php
$routes->post('products', 'Product::feature');
$routes->put('products/1', 'Product::feature');
$routes->delete('products/1', 'Product::feature');
ルートが一致する必要がある複数の動詞を、match()
メソッドに配列として渡すことで指定できます。
<?php
$routes->match(['get', 'put'], 'products', 'Product::feature');
ルートハンドラーの指定
コントローラーの名前空間
コントローラーとメソッド名を文字列として指定する場合、コントローラーが先頭の\
なしで記述されていると、デフォルトの名前空間が先頭に付加されます。
<?php
// Routes to \App\Controllers\Api\Users::update()
$routes->post('api/users', 'Api\Users::update');
先頭に\
を付けると、完全修飾クラス名として扱われます。
<?php
// Routes to \Acme\Blog\Controllers\Home::list()
$routes->get('blog', '\Acme\Blog\Controllers\Home::list');
また、namespace
オプションで名前空間を指定することもできます。
<?php
// Routes to \Admin\Users::index()
$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']);
詳細については、名前空間の割り当てを参照してください。
配列呼び出し構文
バージョン4.2.0で追加されました。
v4.2.0以降、配列呼び出し構文を使用してコントローラーを指定できます。
$routes->get('/', [\App\Controllers\Home::class, 'index']);
または、use
キーワードを使用します。
use App\Controllers\Home;
$routes->get('/', [Home::class, 'index']);
use App\Controllers\Home;
を追加するのを忘れると、コントローラークラス名は、**app/Config/Routes.php**の先頭にnamespace Config;
があるため、App\Controllers\Home
ではなくConfig\Home
として解釈されます。
注意
配列呼び出し構文を使用すると、クラス名は常に完全修飾クラス名として解釈されます。したがって、デフォルトの名前空間と名前空間オプションは効果がありません。
配列呼び出し構文とプレースホルダー
プレースホルダーがある場合、指定された順序で自動的にパラメーターが設定されます。
use App\Controllers\Product;
$routes->get('product/(:num)/(:num)', [Product::class, 'index']);
// The above code is the same as the following:
$routes->get('product/(:num)/(:num)', 'Product::index/$1/$2');
ただし、ルートで正規表現を使用する場合、自動構成されたパラメータが正しくない場合があります。そのような場合は、パラメータを手動で指定できます。
use App\Controllers\Product;
$routes->get('product/(:num)/(:num)', [[Product::class, 'index'], '$2/$1']);
// The above code is the same as the following:
$routes->get('product/(:num)/(:num)', 'Product::index/$2/$1');
クロージャの使用
ルートがマッピングする宛先として、匿名関数、つまりクロージャを使用できます。この関数は、ユーザーがそのURIにアクセスしたときに実行されます。これは、小さなタスクをすばやく実行したり、単純なビューを表示したりするのに便利です。
<?php
use App\Libraries\RSSFeeder;
$routes->get('feed', static function () {
$rss = new RSSFeeder();
return $rss->feed('general');
});
ルートパスの指定
プレースホルダー
典型的なルートは次のようになります。
<?php
$routes->get('product/(:num)', 'Catalog::productLookup');
ルートでは、最初のパラメータにはマッチングされるURIが含まれ、2番目のパラメータにはルーティング先の宛先が含まれます。上記の例では、URLパスの最初のセグメントに「product」というリテラルな単語があり、2番目のセグメントに数値がある場合、代わりにCatalog
クラスとproductLookup
メソッドが使用されます。
プレースホルダーは、正規表現パターンを表す単なる文字列です。ルーティングプロセス中に、これらのプレースホルダーは正規表現の値に置き換えられます。これらは主に可読性のために使用されます。
以下のプレースホルダーをルートで使用できます。
プレースホルダー |
説明 |
---|---|
(:any) |
その時点からURIの末尾までのすべての文字に一致します。これには、複数のURIセグメントが含まれる場合があります。 |
(:segment) |
スラッシュ( |
(:num) |
任意の整数に一致します。 |
(:alpha) |
アルファベット文字の任意の文字列に一致します |
(:alphanum) |
アルファベット文字または整数の任意の文字列、または2つの任意の組み合わせに一致します。 |
(:hash) |
|
注意
{locale}
は、ローカライゼーションで使用するために予約されているため、プレースホルダーやルートの他の部分として使用することはできません。
(:any) の動作
単一の (:any)
は、URLに複数のセグメントが存在する場合、それらに一致することに注意してください。
たとえば、次のルートの場合
<?php
$routes->get('product/(:any)', 'Catalog::productLookup/$1');
product/123、product/123/456、product/123/456/789 などに一致します。
上記の例では、$1
プレースホルダーにスラッシュ(/
)が含まれている場合でも、Catalog::productLookup()
に渡されるときに、複数のパラメータに分割されます。
コントローラでの実装では、パラメータの最大数を考慮する必要があります
<?php
namespace App\Controllers;
class Catalog extends BaseController
{
public function productLookup($seg1 = false, $seg2 = false, $seg3 = false)
{
echo $seg1; // Will be 123 in all examples
echo $seg2; // false in first, 456 in second and third example
echo $seg3; // false in first and second, 789 in third
}
}
または、可変長引数リストを使用できます。
<?php
namespace App\Controllers;
class Catalog extends BaseController
{
public function productLookup(...$params)
{
echo $params[0] ?? null; // Will be 123 in all examples
echo $params[1] ?? null; // null in first, 456 in second and third example
echo $params[2] ?? null; // null in first and second, 789 in third
}
}
重要
(:any)
の後にプレースホルダーを置かないでください。コントローラメソッドに渡されるパラメータの数が変わる可能性があるためです。
複数のセグメントをマッチングすることが意図した動作でない場合は、ルートを定義するときに (:segment)
を使用する必要があります。上記の例のURLでは
<?php
$routes->get('product/(:segment)', 'Catalog::productLookup/$1');
product/123のみに一致し、他の例では404エラーが発生します。
カスタムプレースホルダー
ルートファイルで使用できる独自のプレースホルダーを作成して、エクスペリエンスと可読性を完全にカスタマイズできます。
addPlaceholder()
メソッドを使用して新しいプレースホルダーを追加します。最初のパラメータは、プレースホルダーとして使用する文字列です。2番目のパラメータは、置き換える正規表現パターンです。これは、ルートを追加する前に呼び出す必要があります。
<?php
$routes->addPlaceholder('uuid', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}');
$routes->get('users/(:uuid)', 'Users::show/$1');
正規表現
必要に応じて、正規表現を使用してルーティングルールを定義できます。任意の有効な正規表現と、後方参照が許可されます。
重要
注: 後方参照を使用する場合は、二重バックスラッシュ構文ではなく、ドル記号構文を使用する必要があります。典型的な正規表現ルートは次のようになります。
<?php
$routes->get('products/([a-z]+)/(\d+)', 'Products::show/$1/id_$2');
上記の例では、products/shirts/123のようなURIは、代わりにProducts
コントローラクラスのshow()
メソッドを呼び出し、元の最初と2番目のセグメントが引数として渡されます。
正規表現を使用すると、通常は複数のセグメント間の区切り文字を表すスラッシュ(/
)を含むセグメントもキャッチできます。
たとえば、ユーザーがWebアプリケーションのパスワードで保護された領域にアクセスし、ログイン後に同じページにリダイレクトできるようにしたい場合、次の例が役立つ場合があります。
<?php
$routes->get('login/(.+)', 'Auth::login/$1');
上記の例では、$1
プレースホルダーにスラッシュ(/
)が含まれている場合でも、Auth::login()
に渡されるときに複数のパラメータに分割されます。
正規表現を知らない人で、詳細を学びたい場合は、regular-expressions.infoが最適な出発点になる可能性があります。
注意
プレースホルダーと正規表現を組み合わせて使用することもできます。
ビュールート
バージョン4.3.0で新規追加。
ロジックが関連付けられていないビューをレンダリングしたい場合は、view()
メソッドを使用できます。これは常にGETリクエストとして扱われます。このメソッドは、2番目のパラメータとしてロードするビューの名前を受け入れます。
<?php
// Displays the view in /app/Views/pages/about.php
$routes->view('about', 'pages/about');
ルート内でプレースホルダーを使用する場合、ビュー内の特別な変数である$segments
内でそれらにアクセスできます。これらは、ルートに表示される順序でインデックスが付けられた配列として使用できます。
<?php
// Displays the view in /app/Views/map.php
$routes->view('map/(:segment)/(:segment)', 'map');
// Within the view, you can access the segments with
// $segments[0] and $segments[1] respectively.
ルートのリダイレクト
十分に長く存在するサイトは、移動するページを持つようになるでしょう。addRedirect()
メソッドを使用して、他のルートにリダイレクトする必要があるルートを指定できます。最初のパラメータは、古いルートのURIパターンです。2番目のパラメータは、リダイレクト先の新しいURI、または名前付きルートの名前のいずれかです。3番目のパラメータは、リダイレクトとともに送信する必要があるHTTPステータスコードです。デフォルト値は302
で、一時的なリダイレクトであり、ほとんどの場合に推奨されます。
<?php
$routes->get('users/profile', 'Users::profile', ['as' => 'profile']);
// Redirect to a named route
$routes->addRedirect('users/about', 'profile');
// Redirect to a URI
$routes->addRedirect('users/about', 'users/profile');
// Redirect with placeholder
$routes->get('post/(:num)/comment/(:num)', 'PostsComments::index', ['as' => 'post.comment']);
// Redirect to a URI
$routes->addRedirect('article/(:num)/(:num)', 'post/$1/comment/$2');
// Redirect to a named route
$routes->addRedirect('article/(:num)/(:num)', 'post.comment');
注意
v4.2.0以降、addRedirect()
でプレースホルダーを使用できます。
ページロード中にリダイレクトルートが一致した場合、コントローラがロードされる前に、ユーザーはすぐに新しいページにリダイレクトされます。
環境制限
特定の環境でのみ表示できるルートのセットを作成できます。これにより、テストサーバーや本番サーバーではアクセスできない、開発者のみがローカルマシンで使用できるツールを作成できます。これは、environment()
メソッドで実行できます。最初のパラメータは環境の名前です。このクロージャ内で定義されたルートは、指定された環境からのみアクセスできます。
<?php
$routes->environment('development', static function ($routes) {
$routes->get('builder', 'Tools\Builder::index');
});
任意のHTTP動詞を持つルート
重要
このメソッドは、下位互換性のためだけに存在します。新しいプロジェクトでは使用しないでください。すでに使用している場合でも、別のより適切なメソッドを使用することをお勧めします。
警告
add()
メソッドは便利なように見えますが、より安全であるため、上記で説明したHTTP動詞ベースのルートを常に使用することをお勧めします。CSRF保護を使用する場合、GETリクエストは保護されません。add()
メソッドで指定されたURIがGETメソッドでアクセス可能な場合、CSRF保護は機能しません。
任意のHTTP動詞でルートを定義できます。add()
メソッドを使用できます。
<?php
$routes->add('products', 'Product::feature');
注意
HTTP動詞ベースのルートを使用すると、現在のリクエストメソッドに一致するルートのみが保存されるため、わずかなパフォーマンスの向上も実現します。これにより、一致を検索するときにスキャンするルートが少なくなります。
複数のルートのマッピング
重要
このメソッドは、下位互換性のためだけに存在します。新しいプロジェクトでは使用しないでください。すでに使用している場合でも、別のより適切なメソッドを使用することをお勧めします。
警告
map()
メソッドは、内部でadd()
を呼び出すため、add()
と同様に推奨されません。
add()
メソッドは使いやすいですが、map()
メソッドを使用して一度に複数のルートを操作する方が便利な場合があります。追加する必要のある各ルートに対してadd()
メソッドを呼び出す代わりに、ルートの配列を定義し、それをmap()
メソッドの最初のパラメータとして渡すことができます。
<?php
$multipleRoutes = [
'product/(:num)' => 'Catalog::productLookupById',
'product/(:alphanum)' => 'Catalog::productLookupByName',
];
$routes->map($multipleRoutes);
コマンドラインのみのルート
注意
CLI経由でコントローラを呼び出す代わりに、CLIスクリプトにSparkコマンドを使用することをお勧めします。詳細については、「Sparkコマンドの作成」ページを参照してください。
HTTP動詞ベースのルーティングメソッドで作成されたルートは、CLIからはアクセスできません。しかし、add()
メソッドで作成されたルートは、コマンドラインからアクセスできます。
cli()
メソッドを使用すると、コマンドラインからのみ機能し、Webブラウザからはアクセスできないルートを作成できます。
<?php
$routes->cli('migrate', 'App\Database::migrate');
警告
自動ルーティング (レガシー) を有効にして、コマンドファイルを **app/Controllers** に配置すると、誰でもHTTP経由で自動ルーティング (レガシー) を利用してコマンドにアクセスできるようになります。
グローバルオプション
ルートを作成するためのすべてのメソッド (get()
、post()
、resource() など) は、生成されたルートを変更したり、さらに制限したりできるオプションの配列を受け取ることができます。$options
配列は常に最後のパラメータです。
<?php
$routes->add('from', 'to', $options);
$routes->get('from', 'to', $options);
$routes->post('from', 'to', $options);
$routes->put('from', 'to', $options);
$routes->head('from', 'to', $options);
$routes->options('from', 'to', $options);
$routes->delete('from', 'to', $options);
$routes->patch('from', 'to', $options);
$routes->match(['get', 'put'], 'from', 'to', $options);
$routes->resource('photos', $options);
$routes->map($array, $options);
$routes->group('name', $options, static function () {});
フィルタの適用
コントローラの前または後に実行するフィルタを指定することで、特定のルートの動作を変更できます。これは、認証やAPIロギングで特に便利です。フィルタの値は、文字列または文字列の配列にすることができます。
**app/Config/Filters.php** で定義されているエイリアスに一致させる必要があります。
フィルタのクラス名
フィルタの設定に関する詳細については、コントローラフィルタ を参照してください。
警告
**app/Config/Routes.php** ( **app/Config/Filters.php** ではなく) でルートにフィルタを設定する場合は、自動ルーティング (レガシー) を無効にすることをお勧めします。自動ルーティング (レガシー) が有効になっていると、コントローラが設定されたルートとは異なるURLでアクセスできるようになる可能性があり、その場合、ルートに指定したフィルタは適用されません。自動ルーティングを無効にするには、定義済みルートのみを使用する を参照してください。
エイリアスフィルタ
フィルタ値に、**app/Config/Filters.php** で定義されているエイリアスを指定します。
<?php
$routes->get('admin', ' AdminController::index', ['filter' => 'admin-auth']);
エイリアスフィルタの before()
および after()
メソッドに渡す引数を指定することもできます。
<?php
$routes->post('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']);
クラス名フィルタ
バージョン 4.1.5 で新規追加。
フィルタ値にフィルタのクラス名を指定します。
<?php
$routes->get('admin', ' AdminController::index', ['filter' => \App\Filters\SomeFilter::class]);
複数のフィルタ
バージョン 4.1.5 で新規追加。
重要
*複数のフィルタ* は、デフォルトで無効になっています。これは、後方互換性を損なうためです。使用したい場合は、設定が必要です。詳細については、ルートに対する複数のフィルタ を参照してください。
フィルタ値に配列を指定します。
<?php
$routes->get('admin', ' AdminController::index', ['filter' => ['admin-auth', \App\Filters\SomeFilter::class]]);
フィルタ引数
追加の引数をフィルタに渡すことができます。
<?php
$routes->add('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']);
この例では、配列 ['dual', 'noreturn']
がフィルタの before()
および after()
実装メソッドの $arguments
に渡されます。
名前空間の割り当て
デフォルト名前空間 が生成されたコントローラに付加されますが、オプション配列で namespace
オプションを使用して、異なる名前空間を指定することもできます。値は、変更したい名前空間である必要があります。
<?php
// Routes to \Admin\Users::index()
$routes->get('admin/users', 'Users::index', ['namespace' => 'Admin']);
新しい名前空間は、get、postなどの単一のルートを作成するメソッドの呼び出し中にのみ適用されます。複数のルートを作成するメソッドの場合、新しい名前空間はその関数によって生成されたすべてのルートに付加されます。また、group()
の場合は、クロージャ内で生成されたすべてのルートに付加されます。
ホスト名による制限
オプション配列の一部として、目的のドメインと一緒に「hostname」オプションを渡すことで、ルートのグループをアプリケーションの特定のドメインまたはサブドメインでのみ機能するように制限できます。
<?php
$routes->get('from', 'to', ['hostname' => 'accounts.example.com']);
この例では、指定されたホストは、ドメインが **accounts.example.com** に完全に一致する場合にのみ機能します。メインサイトの **example.com** では機能しません。
サブドメインによる制限
subdomain
オプションが存在する場合、システムはそのサブドメインでのみルートを利用できるように制限します。ルートは、アプリケーションが表示されているサブドメインである場合にのみマッチングされます。
<?php
// Limit to media.example.com
$routes->get('from', 'to', ['subdomain' => 'media']);
値をアスタリスク (*
) に設定することで、任意のサブドメインに制限できます。サブドメインが存在しないURLから表示している場合、これはマッチングされません。
<?php
// Limit to any sub-domain
$routes->get('from', 'to', ['subdomain' => '*']);
重要
システムは完璧ではなく、本番環境で使用する前に、特定のドメインでテストする必要があります。ほとんどのドメインは正常に機能するはずですが、一部の例外的なドメイン、特にドメイン自体にピリオドがあるもの (サフィックスやwwwを区切るために使用されるものではない) は、誤検出につながる可能性があります。
マッチしたパラメータのオフセット
ルートのマッチしたパラメータを、offset
オプションで任意の数値でオフセットできます。値は、オフセットするセグメントの数です。
これは、最初のURIセグメントがバージョン番号であるAPIを開発する場合に役立ちます。最初のパラメータが言語文字列の場合にも使用できます。
<?php
$routes->get('users/(:num)', 'users/show/$1', ['offset' => 1]);
// Creates:
$routes['users/(:num)'] = 'users/show/$2';
リバースルーティング
リバースルーティングを使用すると、リンクが移動するコントローラとメソッド、およびパラメータを定義し、それに対する現在のルートをルーターに検索させることができます。これにより、アプリケーションコードを更新しなくても、ルート定義を変更できます。これは通常、ビュー内でリンクを作成するために使用されます。
たとえば、リンクしたいフォトギャラリーへのルートがある場合、url_to()
ヘルパー関数を使用して、使用するルートを取得できます。最初のパラメータは、初期ルート自体を記述するときと同様に、二重コロン (::
) で区切られた、完全修飾のコントローラとメソッドです。ルートに渡す必要のあるパラメータは、次に渡されます。
<?php
// The route is defined as:
$routes->get('users/(:num)/gallery/(:num)', 'Galleries::showUserGallery/$1/$2');
?>
<!-- Generate the URI to link to user ID 15, gallery 12: -->
<a href="<?= url_to('Galleries::showUserGallery', 15, 12) ?>">View Gallery</a>
<!-- Result: 'http://example.com/users/15/gallery/12' -->
名前付きルート
名前付きルートを使用すると、アプリケーションの脆弱性を軽減できます。これにより、後で呼び出すことができるルートに名前が適用され、ルート定義が変更された場合でも、url_to()
で構築されたアプリケーション内のすべてのリンクは、変更を加えることなく引き続き機能します。ルートは、ルートの名前とともに as
オプションを渡すことで名前が付けられます。
<?php
// The route is defined as:
$routes->get('users/(:num)/gallery/(:num)', 'Galleries::showUserGallery/$1/$2', ['as' => 'user_gallery']);
?>
<!-- Generate the URI to link to user ID 15, gallery 12: -->
<a href="<?= url_to('user_gallery', 15, 12) ?>">View Gallery</a>
<!-- Result: 'http://example.com/users/15/gallery/12' -->
これにより、ビューも読みやすくなるという利点もあります。
ルートのグループ化
group()
メソッドを使用すると、ルートを共通の名前でグループ化できます。グループ名は、グループ内で定義されたルートの前に表示されるセグメントになります。これにより、管理者エリアを構築するときのように、すべてが開始文字列を共有する広範なルートセットを構築するために必要な入力を減らすことができます。
<?php
$routes->group('admin', static function ($routes) {
$routes->get('users', 'Admin\Users::index');
$routes->get('blog', 'Admin\Blog::index');
});
これにより、**users** および **blog** URIに **admin** が付加され、**admin/users** や **admin/blog** のようなURLを処理します。
名前空間の設定
名前空間の割り当て のように、グループにオプションを割り当てる必要がある場合は、コールバックの前に行ってください。
<?php
$routes->group('api', ['namespace' => 'App\API\v1'], static function ($routes) {
$routes->resource('users');
});
これにより、**api/users** URIを使用して App\API\v1\Users
コントローラへのリソースルートが処理されます。
フィルタの設定
ルートのグループに特定の フィルタ を使用することもできます。これにより、コントローラの前後で常にフィルタが実行されます。これは、認証やAPIロギングで特に便利です。
<?php
$routes->group('api', ['filter' => 'api-auth'], static function ($routes) {
$routes->resource('users');
});
フィルタの値は、**app/Config/Filters.php** 内で定義されているエイリアスのいずれかに一致する必要があります。
その他のオプションの設定
場合によっては、フィルタや、名前空間、サブドメインなどの他のルート設定オプションを適用するために、ルートをグループ化することがあります。必ずしもグループにプレフィックスを追加する必要がない場合は、プレフィックスの代わりに空の文字列を渡すことができ、グループ内のルートは、グループが存在しなかったかのようにルーティングされますが、指定されたルート設定オプションが適用されます。
<?php
$routes->group('', ['namespace' => 'Myth\Auth\Controllers'], static function ($routes) {
$routes->get('login', 'AuthController::login', ['as' => 'login']);
$routes->post('login', 'AuthController::attemptLogin');
$routes->get('logout', 'AuthController::logout');
});
グループのネスト
必要に応じて、より細かく整理するために、グループ内にグループをネストすることができます。
<?php
$routes->group('admin', static function ($routes) {
$routes->group('users', static function ($routes) {
$routes->get('list', 'Admin\Users::list');
});
});
これにより、**admin/users/list** のURLが処理されます。
注意
外側の group()
に渡されたオプション (たとえば、namespace
や filter
) は、内側の group()
オプションとマージされません。
ルートの優先度
ルートは、定義された順序でルーティングテーブルに登録されます。これは、URIにアクセスするときに、最初に一致するルートが実行されることを意味します。
警告
ルートパスが異なるハンドラで複数回定義されている場合、最初に定義されたルートのみが登録されます。
ルーティングテーブルに登録されたルートは、spark routes コマンドを実行することで確認できます。
ルートの優先度の変更
モジュールを扱う際、アプリケーション内のルートにワイルドカードが含まれていると問題になることがあります。その場合、モジュールのルートが正しく処理されません。この問題は、priority
オプションを使ってルート処理の優先度を下げることで解決できます。このパラメータは、正の整数とゼロを受け付けます。priority
に指定する数値が大きいほど、処理キューにおけるルートの優先度は低くなります。
<?php
// First you need to enable processing of the routes queue by priority.
$routes->setPrioritize();
// Config\Routes
$routes->get('(.*)', 'Posts::index', ['priority' => 1]);
// Modules\Acme\Config\Routes
$routes->get('admin', 'Admin::index');
// The "admin" route will now be processed before the wildcard route.
この機能を無効にするには、パラメータにfalse
を指定してメソッドを呼び出す必要があります。
<?php
$routes->setPrioritize(false);
注意
デフォルトでは、すべてのルートの優先度は0です。負の整数は絶対値に変換されます。
ルート設定オプション
RoutesCollectionクラスは、すべてのルートに影響を与えるいくつかのオプションを提供しており、アプリケーションのニーズに合わせて変更できます。これらのオプションは、app/Config/Routing.php で利用できます。
注意
設定ファイル app/Config/Routing.php は、v4.4.0 から追加されました。以前のバージョンでは、設定を変更するために app/Config/Routes.php でセッターメソッドが使用されていました。
デフォルト名前空間
コントローラをルートにマッチングさせる際、ルーターは、ルートによって指定されたコントローラの先頭にデフォルトの名前空間の値を追加します。デフォルトでは、この値は App\Controllers
です。
値を空文字列(''
)に設定した場合、各ルートは完全に名前空間化されたコントローラを指定することになります。
<?php
// In app/Config/Routing.php
use CodeIgniter\Config\Routing as BaseRouting;
// ...
class Routing extends BaseRouting
{
// ...
public string $defaultNamespace = '';
// ...
}
// In app/Config/Routes.php
// Controller is \Users
$routes->get('users', 'Users::index');
// Controller is \Admin\Users
$routes->get('users', 'Admin\Users::index');
コントローラが明示的に名前空間化されていない場合は、これを変更する必要はありません。コントローラを名前空間化する場合は、この値を変更してタイプ数を減らすことができます。
<?php
// This can be overridden in app/Config/Routes.php
$routes->setDefaultNamespace('App');
// Controller is \App\Users
$routes->get('users', 'Users::index');
// Controller is \App\Admin\Users
$routes->get('users', 'Admin\Users::index');
URIダッシュの変換
このオプションを使用すると、オートルーティングで使用される際、コントローラとメソッドのURIセグメント内のダッシュ(-
)を自動的にアンダースコアに置き換えることができ、必要に応じて追加のルートエントリを節約できます。これは、ダッシュが有効なクラスまたはメソッド名文字ではなく、それを使用しようとすると致命的なエラーが発生するため、必要です。
<?php
// In app/Config/Routing.php
use CodeIgniter\Config\Routing as BaseRouting;
// ...
class Routing extends BaseRouting
{
// ...
public bool $translateURIDashes = true;
// ...
}
// This can be overridden in app/Config/Routes.php
$routes->setTranslateURIDashes(true);
注意
v4.4.0より前のオートルーティング(改善版)を使用している場合、$translateURIDashes
が true の場合、2つのURIが単一のコントローラメソッドに対応していました。1つのURIはダッシュ(例:foo-bar)用で、もう1つのURIはアンダースコア(例:foo_bar)用でした。これは誤った動作でした。v4.4.0以降、アンダースコア(foo_bar)のURIにはアクセスできません。
定義されたルートのみを使用
v4.2.0以降、オートルーティングはデフォルトで無効になっています。
URIに一致する定義済みルートが見つからない場合、オートルーティングが有効になっていると、システムはそのURIをコントローラとメソッドと照合しようとします。
この自動マッチングを無効にし、$autoRoute
プロパティを false に設定することで、ルートを自分で定義したもののみに制限できます。
<?php
// In app/Config/Routing.php
use CodeIgniter\Config\Routing as BaseRouting;
// ...
class Routing extends BaseRouting
{
// ...
public bool $autoRoute = false;
// ...
}
// This can be overridden in app/Config/Routes.php
$routes->setAutoRoute(false);
警告
CSRF保護を使用している場合、**GET**リクエストは保護されません。URIがGETメソッドでアクセス可能な場合、CSRF保護は機能しません。
404オーバーライド
現在のURIに一致するページが見つからない場合、システムは汎用的な404ビューを表示します。set404Override()
メソッドを使用して実行するアクションを指定することで、動作を変更できます。この値は、通常のルートと同様に有効なクラス/メソッドのペア、またはクロージャにすることができます。
<?php
// In app/Config/Routing.php
use CodeIgniter\Config\Routing as BaseRouting;
// ...
class Routing extends BaseRouting
{
// ...
public ?string $override404 = 'App\Errors::show404';
// ...
}
// In app/Config/Routes.php
// Would execute the show404 method of the App\Errors class
$routes->set404Override('App\Errors::show404');
// Will display a custom view
$routes->set404Override(static function () {
echo view('my_errors/not_found.html');
});
ルーティング設定ファイル内の $override404
プロパティを使用すると、クロージャを使用できます。ルーティングファイルでのオーバーライドの定義は、クラス/メソッドのペアに制限されています。
注意
set404Override()
メソッドは、レスポンスのステータスコードを 404
に変更しません。設定したコントローラでステータスコードを設定しない場合、デフォルトのステータスコード 200
が返されます。ステータスコードの設定方法については、CodeIgniter\HTTP\Response::setStatusCode()
を参照してください。
優先度によるルート処理
優先度によるルートキューの処理を有効または無効にします。優先度の低下は、ルートオプションで定義されます。デフォルトでは無効です。この機能はすべてのルートに影響を与えます。優先度を下げる使用例については、ルート優先度 を参照してください。
<?php
// In app/Config/Routing.php
use CodeIgniter\Config\Routing as BaseRouting;
// ...
class Routing extends BaseRouting
{
// ...
public bool $prioritize = true;
// ...
}
// In app/Config/Routes.php
// to enable
$routes->setPrioritize();
// to disable
$routes->setPrioritize(false);
オートルーティング(改善版)
バージョン4.2.0で追加されました。
v4.2.0以降、新しい、より安全なオートルーティングが導入されました。
注意
CodeIgniter 3から4.1.xまでデフォルトで有効になっていたオートルーティングに精通している方は、ChangeLog v4.2.0 で違いを確認できます。
URIに一致する定義済みルートが見つからない場合、オートルーティングが有効になっていると、システムはそのURIをコントローラとメソッドと照合しようとします。
重要
セキュリティ上の理由から、コントローラが定義されたルートで使用されている場合、オートルーティング(改善版)はそのコントローラにルーティングしません。
オートルーティングは、規約に基づいてHTTPリクエストを自動的にルーティングし、対応するコントローラメソッドを実行できます。
注意
オートルーティング(改善版)はデフォルトで無効になっています。使用するには、以下を参照してください。
オートルーティングの有効化
使用するには、app/Config/Routing.php で $autoRoute
オプションの設定を true
に変更する必要があります。
public bool $autoRoute = true;
また、app/Config/Feature.php でプロパティ $autoRoutesImproved
を true
に変更する必要があります。
public bool $autoRoutesImproved = true;
URIセグメント
モデル-ビュー-コントローラのアプローチに従うと、URL内のセグメントは通常、以下を表します。
example.com/class/method/ID
最初のセグメントは、呼び出すべきコントローラの **クラス** を表します。
2番目のセグメントは、呼び出すべきクラスの **メソッド** を表します。
3番目以降のセグメントは、IDとコントローラに渡される変数を示します。
次のURIを考えてみましょう。
example.com/index.php/helloworld/hello/1
上記の例では、**GET** メソッドで HTTP リクエストを送信すると、オートルーティングは App\Controllers\Helloworld
という名前のコントローラを検索し、'1'
を最初の引数として渡して getHello()
メソッドを実行します。
注意
オートルーティング(改善版)によって実行されるコントローラメソッドには、HTTP動詞(get
、post
、put
など)のプレフィックス(getIndex()
、postCreate()
など)が必要です。
詳細については、コントローラのオートルーティングを参照してください。
設定オプション
これらのオプションは、app/Config/Routing.php ファイルで利用できます。
デフォルトコントローラ
サイトルートURIの場合
ユーザーがサイトのルート(つまり、example.com)にアクセスした場合、明示的にルートが存在しない限り、使用するコントローラは $defaultController
プロパティに設定された値によって決定されます。
このデフォルト値は Home
で、app/Controllers/Home.php のコントローラと一致します。
public string $defaultController = 'Home';
ディレクトリURIの場合
デフォルトコントローラは、一致するルートが見つからず、URIがコントローラディレクトリ内のディレクトリを指している場合にも使用されます。たとえば、ユーザーが example.com/admin にアクセスした場合、app/Controllers/Admin/Home.php にコントローラが見つかれば、それが使用されます。
重要
コントローラ名URIでデフォルトコントローラにアクセスすることはできません。デフォルトコントローラが Home
の場合、example.com/ にアクセスできますが、example.com/home にアクセスすると見つかりません。
詳細については、コントローラのオートルーティングを参照してください。
デフォルトメソッド
これはデフォルトコントローラの設定と同様に機能しますが、URIに一致するコントローラが見つかったが、メソッドのセグメントが存在しない場合に使用されるデフォルトメソッドを決定するために使用されます。デフォルト値は index
です。
この例では、ユーザーが example.com/products にアクセスし、Products
コントローラが存在する場合、Products::getListAll()
メソッドが実行されます。
public string $defaultMethod = 'listAll';
重要
デフォルトメソッド名URIでコントローラにアクセスすることはできません。上記の例では、example.com/products にアクセスできますが、example.com/products/listall にアクセスすると見つかりません。
モジュールルーティング
バージョン 4.4.0 で新しく追加されました。
コードモジュールを使用し、コントローラーを別の名前空間に配置している場合でも、自動ルーティングを使用できます。
モジュールへルーティングするには、app/Config/Routing.php 内の $moduleRoutes
プロパティを設定する必要があります。
public array $moduleRoutes = [
'blog' => 'Acme\Blog\Controllers',
];
キーはモジュールの最初の URI セグメントであり、値はコントローラーの名前空間です。上記の構成では、https://:8080/blog/foo/bar は Acme\Blog\Controllers\Foo::getBar()
にルーティングされます。
注意
$moduleRoutes
を定義した場合、モジュールのルーティングが優先されます。上記の例では、App\Controllers\Blog
コントローラーがある場合でも、https://:8080/blog はデフォルトのコントローラー Acme\Blog\Controllers\Home
にルーティングされます。
自動ルーティング (レガシー)
重要
この機能は後方互換性のためだけに存在します。新しいプロジェクトでは使用しないでください。すでに使用している場合でも、代わりに 自動ルーティング (改善版) を使用することをお勧めします。
自動ルーティング (レガシー) は、CodeIgniter 3 のルーティングシステムです。規約に基づいて HTTP リクエストを自動的にルーティングし、対応するコントローラーメソッドを実行できます。
すべてのルートを app/Config/Routes.php ファイルに定義するか、自動ルーティング (改善版) を使用することをお勧めします。
警告
設定ミスやコーディングミスを防ぐため、自動ルーティング (レガシー) 機能を使用しないことをお勧めします。コントローラーフィルターや CSRF 保護がバイパスされる脆弱なアプリを簡単に作成できます。
重要
自動ルーティング (レガシー) は、あらゆる HTTP メソッドを持つ HTTP リクエストをコントローラーメソッドにルーティングします。
自動ルーティング (レガシー) の有効化
v4.2.0以降、オートルーティングはデフォルトで無効になっています。
使用するには、app/Config/Routing.php で $autoRoute
オプションの設定を true
に変更する必要があります。
public bool $autoRoute = true;
app/Config/Feature.php 内のプロパティ $autoRoutesImproved
を false
に設定します。
public bool $autoRoutesImproved = false;
URI セグメント (レガシー)
モデル-ビュー-コントローラのアプローチに従うと、URL内のセグメントは通常、以下を表します。
example.com/class/method/ID
最初のセグメントは、呼び出すべきコントローラの **クラス** を表します。
2番目のセグメントは、呼び出すべきクラスの **メソッド** を表します。
3番目以降のセグメントは、IDとコントローラに渡される変数を示します。
次のURIを考えてみましょう。
example.com/index.php/helloworld/index/1
上記の例では、CodeIgniter は Helloworld.php という名前のコントローラーを見つけ、'1'
を最初の引数として渡して index()
メソッドを実行しようとします。
詳細については、コントローラーの自動ルーティング (レガシー) を参照してください。
構成オプション (レガシー)
これらのオプションは、app/Config/Routing.php ファイルで利用できます。
デフォルトコントローラー (レガシー)
サイトルート URI (レガシー) の場合
ユーザーがサイトのルート(つまり、example.com)にアクセスした場合、明示的にルートが存在しない限り、使用するコントローラは $defaultController
プロパティに設定された値によって決定されます。
このデフォルト値は Home
で、app/Controllers/Home.php のコントローラと一致します。
public string $defaultController = 'Home';
ディレクトリ URI (レガシー) の場合
デフォルトコントローラは、一致するルートが見つからず、URIがコントローラディレクトリ内のディレクトリを指している場合にも使用されます。たとえば、ユーザーが example.com/admin にアクセスした場合、app/Controllers/Admin/Home.php にコントローラが見つかれば、それが使用されます。
詳細については、コントローラーの自動ルーティング (レガシー) を参照してください。
デフォルトメソッド (レガシー)
これはデフォルトコントローラの設定と同様に機能しますが、URIに一致するコントローラが見つかったが、メソッドのセグメントが存在しない場合に使用されるデフォルトメソッドを決定するために使用されます。デフォルト値は index
です。
この例では、ユーザーが example.com/products にアクセスし、Products
コントローラーが存在する場合、Products::listAll()
メソッドが実行されます。
public string $defaultMethod = 'listAll';
ルートの確認
CodeIgniter には、すべてのルートを表示する次の コマンド があります。
spark routes
すべてのルートとフィルターを表示します。
php spark routes
出力は次のようになります。
+---------+---------+---------------+-------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+---------+---------+---------------+-------------------------------+----------------+---------------+
| GET | / | » | \App\Controllers\Home::index | | toolbar |
| GET | feed | » | (Closure) | | toolbar |
+---------+---------+---------------+-------------------------------+----------------+---------------+
Method 列には、ルートがリッスンする HTTP メソッドが表示されます。
Route 列には、一致させるルートパスが表示されます。定義されたルートのルートは、正規表現として表現されます。
v4.3.0 以降、Name 列にはルート名が表示されます。»
は、名前がルートパスと同じであることを示します。
重要
システムは完璧ではありません。([^/]+)
や {locale}
のような正規表現パターンを含むルートの場合、表示される *Filters* が正しくない場合(**app/Config/Filters.php** でフィルターの複雑な URI パターンを設定した場合)、または <unknown>
として表示される場合があります。
spark filter:check コマンドを使用すると、100% 正確なフィルターを確認できます。
自動ルーティング (改善版)
自動ルーティング (改善版) を使用すると、出力は次のようになります。
+-----------+-------------------------+---------------+-----------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+-----------+-------------------------+---------------+-----------------------------------+----------------+---------------+
| GET(auto) | product/list/../..[/..] | | \App\Controllers\Product::getList | | toolbar |
+-----------+-------------------------+---------------+-----------------------------------+----------------+---------------+
Method は GET(auto)
のようになります。
Route 列の /..
は 1 つのセグメントを示します。[/..]
はそれがオプションであることを示します。
注意
自動ルーティングが有効で、ルート home
がある場合、Home
、あるいは hOme
、hoMe
、HOME
などでもアクセスできますが、コマンドは home
のみを表示します。
次のように x
で始まるルートが表示される場合は、ルーティングされない無効なルートを示しますが、コントローラーにはルーティング用のパブリックメソッドがあります。
+-----------+----------------+------+-------------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+-----------+----------------+------+-------------------------------------+----------------+---------------+
| GET(auto) | x home/foo | | \App\Controllers\Home::getFoo | <unknown> | <unknown> |
+-----------+----------------+------+-------------------------------------+----------------+---------------+
上記の例は、\App\Controllers\Home::getFoo()
メソッドがあることを示していますが、デフォルトコントローラー (Home
がデフォルト) であり、デフォルトコントローラーの名前は URI で省略する必要があるため、ルーティングされません。getFoo()
メソッドを削除する必要があります。
注意
v4.3.4 より前では、バグのために無効なルートが通常のルートとして表示されていました。
自動ルーティング (レガシー)
自動ルーティング (レガシー) を使用すると、出力は次のようになります。
+--------+--------------------+---------------+-----------------------------------+----------------+---------------+
| Method | Route | Name | Handler | Before Filters | After Filters |
+--------+--------------------+---------------+-----------------------------------+----------------+---------------+
| auto | product/list[/...] | | \App\Controllers\Product::getList | | toolbar |
+--------+--------------------+---------------+-----------------------------------+----------------+---------------+
Method は auto
になります。
Route 列の [/...]
は、任意の数のセグメントを示します。
注意
自動ルーティングが有効で、ルート home
がある場合、Home
、あるいは hOme
、hoMe
、HOME
などでもアクセスできますが、コマンドは home
のみを表示します。
ハンドラーでソート
バージョン4.3.0で新規追加。
ルートを *Handler* でソートできます。
php spark routes -h
ホストの指定
バージョン 4.4.0 で新しく追加されました。
--host
オプションを使用して、リクエスト URL でホストを指定できます。
php spark routes --host accounts.example.com