CodeIgniterのフィルタ機能を完全ガイド!初心者でもわかるイベント・フィルタの使い方
生徒
「CodeIgniterで、ページを表示する前に何か処理を実行する方法ってありますか?」
先生
「はい、あります。CodeIgniterには、フィルタという便利な機能があって、コントローラーの前後に処理を挟み込むことができますよ。」
生徒
「フィルタですか?具体的にはどんな時に使うんですか?」
先生
「例えば、ログインしているかチェックしたり、アクセス権限を確認したりする時に使います。それでは、フィルタの作成方法と登録方法を順番に見ていきましょう!」
1. CodeIgniterのフィルタとは?
CodeIgniterのフィルタは、コントローラーのメソッドが実行される前後に、自動的に処理を実行する仕組みです。イメージとしては、家に入る前に玄関で靴を脱ぐように、ページを表示する前に必ず通過するチェックポイントのようなものです。
フィルタを使うことで、すべてのページで共通して行いたい処理を一箇所にまとめることができます。例えば、ログイン認証、権限チェック、データの前処理、セキュリティチェックなど、様々な用途で活用できます。
イベント・フィルタ機能とは、特定のイベント(ページ表示前や表示後など)が発生した時に、自動的にフィルタが動作する仕組みのことです。CodeIgniter4から本格的に導入された機能で、開発効率を大きく向上させることができます。
2. フィルタが実行されるタイミング
CodeIgniterのフィルタには、実行されるタイミングが2つあります。
before(ビフォー):コントローラーのメソッドが実行される前に動作します。ページを表示する前に、ログインチェックやアクセス制限を行う時に使います。
after(アフター):コントローラーのメソッドが実行された後に動作します。ページを表示した後に、ログを記録したり、データを加工したりする時に使います。
この2つのタイミングを使い分けることで、柔軟な処理の流れを作ることができます。例えば、お店に例えると、beforeは「入店時の検温」、afterは「退店時のレシート発行」のようなイメージです。
3. フィルタファイルを作成する基本手順
それでは実際にフィルタを作成してみましょう。フィルタはapp/Filtersというフォルダの中に作成します。
まず、フィルタクラスを作成します。ここでは、ログインチェックを行うAuthFilterという名前のフィルタを作ってみます。
<?php
namespace App\Filters;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
class AuthFilter implements FilterInterface
{
public function before(RequestInterface $request, $arguments = null)
{
// ログインチェックの処理
if (!session()->get('isLoggedIn')) {
return redirect()->to('/login');
}
}
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// 処理後に実行したい内容があればここに書く
}
}
このコードでは、FilterInterfaceというインターフェースを実装しています。インターフェースとは、クラスが必ず実装しなければならないメソッドを定義したものです。契約書のようなもので、「このメソッドは必ず用意してください」という約束事を決めています。
beforeメソッドの中で、セッションにisLoggedInという値がない場合は、ログインページにリダイレクトしています。セッションとは、ユーザーの情報を一時的に保存しておく仕組みで、ログイン状態などを記憶するために使われます。
4. フィルタを登録する設定ファイルの編集
作成したフィルタを実際に使えるようにするには、app/Config/Filters.phpという設定ファイルに登録する必要があります。このファイルは、どのフィルタをどこで使うかを管理する、いわば「フィルタの住所録」のようなものです。
まず、$aliasesという配列に、フィルタの別名を登録します。
<?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,
'auth' => \App\Filters\AuthFilter::class, // 追加
];
public $globals = [
'before' => [
// 'honeypot',
// 'csrf',
],
'after' => [
'toolbar',
],
];
}
ここでは、'auth'という短い名前で、先ほど作成したAuthFilterクラスを呼び出せるように設定しています。エイリアス(別名)を使うことで、長いクラス名を毎回書かなくても済むようになります。
5. フィルタを特定のルートに適用する方法
フィルタを特定のページだけに適用したい場合は、app/Config/Filters.phpの$filters配列を使います。
public $filters = [
'auth' => [
'before' => ['dashboard', 'profile/*', 'admin/*'],
'after' => []
],
];
この設定では、dashboard、profileで始まるURL、adminで始まるURLにアクセスする前に、必ずauthフィルタが実行されます。アスタリスク(*)はワイルドカードと呼ばれ、「どんな文字列でもOK」という意味です。
つまり、profile/editやprofile/settingsなど、profileで始まるすべてのページに適用されます。これにより、管理画面など、ログインが必要なページ全体を保護することができます。
6. ルートファイルで個別にフィルタを指定する方法
app/Config/Routes.phpというルート設定ファイルで、個別のルートにフィルタを適用することもできます。この方法は、より細かい制御が必要な時に便利です。
$routes->get('dashboard', 'Dashboard::index', ['filter' => 'auth']);
$routes->group('admin', ['filter' => 'auth'], function($routes) {
$routes->get('users', 'Admin::users');
$routes->get('settings', 'Admin::settings');
});
['filter' => 'auth']というオプションを追加することで、そのルートにアクセスする時にフィルタが実行されます。groupメソッドを使うと、複数のルートをまとめて同じフィルタを適用できます。
グループ化は、関連するページをまとめて管理するのに便利です。例えば、管理画面のすべてのページに認証フィルタを適用したい場合、一つ一つ設定するのではなく、グループとしてまとめて設定できます。
7. すべてのページにフィルタを適用するグローバル設定
すべてのページで実行したいフィルタは、app/Config/Filters.phpの$globals配列に登録します。これはグローバルフィルタと呼ばれ、サイト全体に影響します。
例えば、すべてのページでCSRF対策(クロスサイトリクエストフォージェリ対策)を行いたい場合は、次のように設定します。
public $globals = [
'before' => [
'csrf',
],
'after' => [
'toolbar',
],
];
CSRF対策とは、悪意のある第三者が勝手にフォームを送信するのを防ぐセキュリティ対策です。オンラインバンキングなどで、本人以外が勝手に送金できないようにする仕組みと同じです。
ただし、グローバルフィルタは全ページに影響するため、設定する際は慎重に検討する必要があります。ログインページなど、フィルタを適用したくないページがある場合は、除外設定も可能です。
8. フィルタに引数を渡す応用テクニック
フィルタには、引数を渡すこともできます。これにより、同じフィルタでも異なる動作をさせることができます。
例えば、ユーザーの権限レベルをチェックするフィルタを作る場合、どのレベル以上が必要かを引数で指定できます。ルート設定で次のように記述します。
$routes->get('admin/users', 'Admin::users', ['filter' => 'auth:admin,editor']);
フィルタ側では、$argumentsパラメータで受け取ることができます。コロン(:)の後に書いた値が配列として渡されます。カンマで区切ることで、複数の値を渡せます。
この機能を使うと、一つのフィルタクラスで、様々な権限チェックパターンに対応できるため、コードの再利用性が高まります。管理者専用ページ、編集者専用ページなど、権限レベルに応じた制御が簡単に実装できます。
9. フィルタ作成時の注意点とベストプラクティス
フィルタを作成する際には、いくつか気をつけるべきポイントがあります。
まず、beforeメソッドでreturn文を使うと、その後の処理(コントローラーのメソッド)は実行されません。これは、ログインしていない場合にページを表示させないようにする時に使います。
逆に、returnしない場合は、フィルタの処理が終わった後、通常通りコントローラーのメソッドが実行されます。フィルタはチェックポイントであり、問題がなければ通過させるという考え方です。
また、フィルタの中で重い処理を行うと、すべてのページの表示速度が遅くなってしまいます。データベースへの複雑な問い合わせなど、時間がかかる処理はできるだけ避けましょう。
フィルタは、シンプルで高速な処理に留めることが、パフォーマンスの良いアプリケーションを作る秘訣です。必要最小限のチェックだけを行い、詳細な処理はコントローラー側で行うようにしましょう。
10. 実際の開発でよく使うフィルタの例
実際の開発現場では、様々なフィルタが使われています。代表的な例をいくつか紹介します。
認証フィルタ:ログインしているかチェックし、未ログインの場合はログインページにリダイレクトします。会員専用ページなどで必須です。
権限チェックフィルタ:ユーザーの権限レベルを確認し、管理者専用ページへのアクセスを制限します。一般ユーザーが管理画面にアクセスできないようにします。
メンテナンスモードフィルタ:サイトがメンテナンス中の場合、すべてのアクセスをメンテナンスページに誘導します。システム更新時などに使用します。
ログ記録フィルタ:ユーザーのアクセス履歴を記録します。誰がいつどのページにアクセスしたかを追跡できます。
API認証フィルタ:APIキーやトークンの有効性を確認し、正当なリクエストのみを受け付けます。外部からのAPI利用を制御します。
これらのフィルタを組み合わせることで、セキュアで使いやすいWebアプリケーションを構築できます。フィルタ機能を活用することで、コードの重複を減らし、メンテナンスしやすいシステムを作ることができます。