CodeIgniter 4で特定ルートにフィルタを適用する方法!初心者向け完全解説
生徒
「CodeIgniterを使っているのですが、特定のページだけにログインチェックをかけたい場合はどうすればいいですか?」
先生
「それは『フィルタ機能』を使うのが一番スマートですね。特定のルート、つまり特定のURLにだけ、処理を挟み込むことができるんですよ。」
生徒
「全てのページじゃなくて、一部のページだけに適用する設定方法を教えてください!」
先生
「もちろんです。初心者の方でも設定ファイルの見方さえ分かれば簡単ですので、一緒に見ていきましょう!」
1. CodeIgniterのフィルタ(Filters)とは?
PHPの人気フレームワークであるCodeIgniter 4(コードイグナイター4)には、「フィルタ」という非常に便利な機能があります。プログラミングを始めたばかりの方には少し聞き慣れない言葉かもしれませんが、これは「検問所」のようなものだと考えてください。
Webサイトには、誰でも見ることができる「トップページ」や「記事一覧」だけでなく、ログインした人しか見ることができない「マイページ」や、管理者しか操作できない「編集画面」などがありますよね。こうした特定のページにアクセスしようとしたときに、「この人はログインしているかな?」や「不正な操作をしていないかな?」といったチェックを自動的に行ってくれるのがフィルタの役割です。
本来、こうしたチェック処理を全てのプログラムに書き込むのは大変な作業です。しかし、CodeIgniterのフィルタ機能を使えば、一箇所に設定を書くだけで、複数のページにまとめてルールを適用することができます。今回は、その中でも特に重要な「特定のルート(URL)にのみフィルタを適用する方法」について詳しく解説していきます。
2. ルート(Routes)という言葉の意味を理解しよう
設定に入る前に、「ルート(Route)」という言葉について解説します。パソコンやインターネットの世界でルートとは、いわば「住所」や「道筋」のことです。例えば、あなたのブログのURLが https://example.com/login だとしたら、この末尾にある login の部分がルートにあたります。
CodeIgniterでは、このルートごとに「どのプログラム(コントローラー)を動かすか」を決めています。そして、フィルタ機能を設定する際も、「このルート(住所)にアクセスが来たら、フィルタという検問所を通しなさい」と指示を出すことになります。特定のルートにのみ適用するということは、特定の住所にだけ特別な警備員を配置するようなイメージですね。これにより、サイト全体の動きを自由自在にコントロールできるようになります。
3. フィルタを適用するための設定ファイルの場所
CodeIgniterでフィルタの設定を行うには、特定のファイルを編集する必要があります。初心者の方が一番迷うのが「どのファイルを触ればいいの?」という点ですが、安心してください。編集するのは主に以下の2つのファイルだけです。
- app/Config/Filters.php:フィルタ全体の「ルール」や「名前」を登録する場所です。
- app/Config/Routes.php:どのURLにどのフィルタを適用するかを、より細かく指定できる場所です。
基本的には、まず Filters.php でフィルタに名前を付け(あだ名を付けるようなものです)、その後に適用範囲を決めるという流れになります。もし、全てのページに一括で適用したい場合は Filters.php だけで完結しますが、特定のページだけに適用したい場合は、Routes.php を使うのが最も直感的で間違いが少ない方法です。まずは、フィルタの基本的な登録方法をコードで見てみましょう。
namespace Config;
use CodeIgniter\Config\BaseConfig;
// 使うフィルタを読み込むための設定
class Filters extends BaseConfig
{
// フィルタの名前にクラス名を割り当てる
public $aliases = [
'csrf' => \CodeIgniter\Filters\CSRF::class,
'toolbar' => \CodeIgniter\Filters\DebugToolbar::class,
'honeypot' => \CodeIgniter\Filters\Honeypot::class,
'authCheck' => \App\Filters\LoginFilter::class, // 自作のログインチェックフィルタ
];
}
4. Routes.phpで特定のルートにフィルタをかける方法
それでは、本題である「特定のルートにのみフィルタを適用する」具体的な書き方を解説します。これには app/Config/Routes.php というファイルを使用します。このファイルは、Webサイトの「地図」のような役割を果たしており、どのURLに対してどの処理を行うかを定義しています。
特定のルートにフィルタを適用するには、$routes->get() や $routes->post() といったメソッドの第3引数(3番目の設定項目)に、['filter' => 'フィルタ名'] という形で記述します。これにより、そのURLにアクセスがあった時だけ、指定したフィルタが起動するようになります。以下のサンプルコードでは、会員専用ページにだけログインチェックフィルタを適用する例を示しています。
// 会員専用の「マイページ」にだけフィルタを適用する
$routes->get('mypage', 'UserController::index', ['filter' => 'authCheck']);
// フィルタを適用しない通常のページ
$routes->get('home', 'Home::index');
// 複数のページをまとめたグループに適用する場合
$routes->group('admin', ['filter' => 'authCheck'], function($routes) {
$routes->get('dashboard', 'AdminController::dashboard');
$routes->get('settings', 'AdminController::settings');
});
このように書くことで、mypage や admin/dashboard にアクセスした時だけ、ログインしているかどうかのチェックが走ります。一方で、home へのアクセスにはフィルタがかからないため、誰でも自由に閲覧することができます。非常にシンプルで分かりやすいですよね。
5. 条件に合わせたフィルタの使い分け(引数の渡し方)
フィルタ機能はただ実行するだけでなく、場合によって「引数(ひきすう)」という追加情報を渡すこともできます。引数とは、プログラムに渡す「命令のオプション」のようなものです。例えば、「このページは管理者(admin)権限が必要」「このページは一般ユーザー(user)権限でOK」といった具合に、同じフィルタを使いつつ条件を細かく変えたい時に役立ちます。
書き方は簡単で、フィルタ名の後ろにコロン(:)を付けて、その後に渡したい情報を記述します。これにより、一つのフィルタプログラムを使い回しながら、ページごとに異なるアクセス制限をかけるといった高度な処理が可能になります。未経験の方には少し難しく感じるかもしれませんが、「オプションを付けて、フィルタの厳しさを調整できるんだな」くらいの理解で大丈夫です。
// 権限チェックフィルタに 'admin' というオプションを渡す例
$routes->get('admin/delete', 'AdminController::delete', ['filter' => 'roleCheck:admin']);
// 権限チェックフィルタに 'editor' というオプションを渡す例
$routes->get('blog/edit', 'BlogController::edit', ['filter' => 'roleCheck:editor']);
上記の例では、roleCheck というフィルタに対して、管理ページでは「admin」、編集ページでは「editor」という情報を送っています。フィルタ側でこの情報を受け取ることにより、「admin権限がないからこの操作はダメですよ」といった判定ができるようになります。プログラムの重複を減らし、スッキリとしたコードを書くための大切なテクニックです。
6. フィルタ適用の優先順位と注意点
最後に、フィルタを適用する際の注意点についてお話しします。CodeIgniterでは、複数の場所でフィルタを設定することができますが、それらが実行される順番には決まりがあります。一般的には「グローバルフィルタ(全ページ共通)」が最初に動き、その後に「特定のルートごとのフィルタ」が動きます。
もし、特定のページでフィルタが上手く動かない場合は、以下のポイントをチェックしてみてください。
- スペルミスはないか:フィルタのあだ名(エイリアス)が、
Filters.phpとRoutes.phpで一致しているか確認しましょう。 - セミコロンを忘れていないか:PHPの命令の終わりには必ず
;が必要です。 - コントローラー名は正しいか:URLの行き先となるコントローラーが正しく存在しているか確認しましょう。
また、フィルタの中で「リダイレクト(別のページに強制移動させる処理)」を行う場合は、無限ループに注意が必要です。例えば「ログインしていない人をログインページに飛ばす」というフィルタを、ログインページ自体にかけてしまうと、永遠にログインページを呼び出し続けてエラーになってしまいます。特定のルートにだけ適用する方法をマスターすれば、こうしたミスも防ぎやすくなります。それでは、最後に応用編として、複数のフィルタを同時に適用する書き方を紹介します。
// 一つのページに「ログインチェック」と「ログ記録」の2つのフィルタをかける
$routes->get('special-report', 'ReportController::show', [
'filter' => ['authCheck', 'logVisitor']
]);
このように配列 [] を使うことで、複数の検問所を順番に通らせることも可能です。まずは一つずつ確実に設定できるようになりましょう!