codeigniter4 におけるルーティングの設定について
この記事は2023/04/01に作成されました。
はじめに
CodeigniterはMVCアーキテクチャ(Model-View-Controller)で成り立っているPHPのフレームワークです。
MVCとはつまり、コードの構造を「DBとのやりとりやデータの処理を行うModel」「ユーザーに実際に表示するページのコードを描くView」「そのModelとViewを接続し、実際のURL構造にも影響するController」の3つに分割しているものを指します。
自動ルーティングについて
Codeigniterでは、「自動ルーティング設定」をONにしていると、Controllerとその中のメソッド名がURLになります。
例えば、「
User」
というControllerに「detail」というメソッドがある場合、自動ルーティングが有効になっていると、そのURLは example.com/user/detailとなります。
class User extends Controller{
public function detail(){
//ここで書いた内容がexample.com/user/detail で表示できるようになる
}
}
さて、Codeigniter3、及びCodeigniter4のVer4.1.9までは前述の自動ルーティングが行われていたのですが
Codeignite4のVer4.2.0からはデフォルト設定では無効化され、「推奨しない」となっています。
(もちろんセキュリティ上の問題は出てきてしまいますが、使うこともできます)
何故推奨されなくなった?
推奨されなくなった理由はいくつか存在しますが、例としては「誤ってページが公開されてしまうこと」や「URLが予測出来てしまうこと」が上げられます。
Codeigniterの自動ルーティングは、URLがコントローラー名とメソッド名に紐づいています。わかりやすい部分ではあるのですが、これを自動で処理してしまうとそれらに対応するURLが自動的に生成される=外部からアクセスが可能になり、デバッグ用や内部でのみ使用するようなメソッドが誤って公開されることでセキュリティ上のリスクが生じる可能性があります。
また、明確な意図を持ってルーティング設定を行わずとも、すぐにアクセス可能なURLが生成されるため、アクセス制限や認証を適切に設定していないと意図せずユーザーがアクセスできてしまう、というリスクが高まります。
Codeigniter 4 におけるルーティング
codeigniter 4におけるルーティングは、「app/Config/Routes.php」に記載することで行います。
上に上げたような、「example.com/user/detail」というURLにて「User」Controllerの「detail」メソッドを表示できるようにするには、以下のように記載します。
$routes->get('user/detail', 'User::detail');
以上のようにRoutes.phpに記載すると、前述のURLでのアクセスが可能になります。
また、$routes->getが示す通り、これは「getリクエスト」のみ可能としてます。
postを送りたいときはは、以下のように指定します。
$routes->post('user/detail', 'User::detail');
こちらがpostということは何故先程のは$routes->get?別に値を送っているわけでもない(example.com/user/detail?test=2)のに?と思われるかもしれませんが、そもそもとして普通にウェブブラウザでURLにアクセスするだけの場合でも実際にはGETリクエストが送信されているため、正しい挙動となりますね。
ただ実際の所、同じURLでgetもpostも両方使いたいという場面は多くあるかと思います。
そういった場合は、matchを使います。
$routes->match(['get', 'post'], 'user/detail', 'User::detail');
第一引数に使いたいリクエストを配列で送り、その後はこれまでと同様URL、コントローラー・メソッドを渡します。
これでgetもpostも利用可能なURLとなります。
また、ユーザーデータを管理して表示するページなど、「末尾のIDが変わる事によって表示するユーザーを変えたい」という事が確実にあるでしょう。
そういった場合には、以下のように記述します。
$routes->match(['get', 'post'], 'user/detail/(:num)', 'User::detail/$1');
class User extends Controller{
public function detail($userId){
//ここで書いた内容がexample.com/user/detail/$userId で表示できるようになる。
//$userIdを使用して、modelからユーザー情報などをロードするといい。
}
}
第二引数のURL指定の後ろに(:num)を付けることで、数字を渡す事ができます。(つまりnumberですね)。
また、第三引数のメソッド名前には/$1といった値を付けます。これが渡した数字に対応します。
私方にはnum以外にも複数あります。以下はCodeigniter 4 マニュアルから引用したものです。
- (:any) は URL のその位置から最後までのすべての文字に一致します。これは複数の URI セグメントを持ちえます。
- (:segment) はスラッシュ (/) を除くすべての文字に一致し、結果としてひとつのセグメントに限定します。
- (:num) はすべての数字に一致します。
- (:alpha) はすべての英字に一致します。
- (:alphanum) はすべての英数字に一致します。
- (:hash) は :segment と同じですが、ハッシュ ID であることを見分けやすくするために使います(モデル ドキュメントをご覧ください)。
また、複数個登録することで複数の値を渡す事ができます。
$routes->match(['get', 'post'], 'user/detail/(:num)/(:any)', 'User::detail/$1/$2');
class User extends Controller{
public function detail($userId,$number2){
//ここで書いた内容がexample.com/user/detail で表示できるようになる
}
}
ちなみに、今回はURLとコントローラー名、メソッド名を同じにしていましたが
実際は全く別なものを付ける事もできます。適宜管理しやすい付け方をするといいでしょう。
その他のルート設定について
routes.phpでできる他の設定についてもいくつか紹介します。
routes.phpでは「デフォルトコントローラーの設定」、つまりサイトトップページの設定も行います。
$routes->setDefaultController('Index');
このRoutes.phpの中で、404ページの設定も可能です。
$routes->set404Override('App\Errors::show404');
$routes->set404Override(function(){
echo view('404.html');
});
404ページの設定はには2パターンあり、特定のController及びメソッドを設定する方法、
及びroutes.phpの中で直接表示するファイルを指定する方法もあります。
また、複数のURLをグルーピングして設定することもできます。
$routes->group('user', function($routes) {
$routes->get('detail', 'User::detail');
$routes->get('edit', 'User::edit');
});
これはUserControllerのdetail、editというメソッドをそれぞれuser/detail・user/editと指定しています。
勿論個別に設定することも可能ですが、コードの視認性という面ではこちらを使うのも良いでしょう。
おわりに
以上のように、Codeigniterでは柔軟なURLとルーティングの設定ができます。
今回はCodeigniter 4の設定について上げましたが、これらはCodeigniter 3でも可能です。
正直自動ルーティングをオンにする事による手間は増えてしまったのですが、その分セキュアであること、
また自由なURL設定ができることから、上手く使いこなせばむしろ便利な設定となるでしょう。
プログラマー/S.Y