CodeIgniter 4は、軽量かつ高速なPHPフレームワークとして知られていますが、ただシンプルなだけでなく、柔軟性の高い設計が魅力のひとつです。その中でも、「フック(Hooks)」という機能は、システムの各所に任意の処理を差し込むことができる非常に強力な拡張機構です。
この記事では、CodeIgniter 4のHooksについて以下の観点から詳しく解説します。
- フックの基本概念と役割
- 使用できるイベントの一覧とタイミング
- 実用的なサンプルコード
- サービスプロバイダを活用した高度なフック管理
- 実運用における注意点とベストプラクティス
初心者の方はもちろん、すでにCodeIgniter 4を業務で利用している中級者以上の方にも、実践的な活用のヒントとなる内容を網羅的に解説します。
フックとは何か?CodeIgniterにおける位置づけ
フックとは、CodeIgniterのライフサイクルの特定ポイントに処理を追加できる仕組みです。たとえば、「すべてのリクエストが来る前にIP制限をかけたい」「コントローラが実行される直前にログ出力したい」といったニーズに対して、コアコードを汚さずスマートに対応できます。
CodeIgniter 3では、application/config/hooks.php
に配列形式で記述するややレガシーな形式でしたが、CodeIgniter 4ではよりモダンに、イベントベースでの登録が可能になりました。これにより、PHPのオブジェクト指向的な設計とも親和性が高まり、テスト可能なコード設計も容易になります。
利用可能なイベント一覧と活用例
CodeIgniter 4では、以下のようなイベントが用意されており、アプリケーションの特定のタイミングで処理を挟むことが可能です。
イベント名 | 発火タイミング | 主な用途・使用例 |
---|---|---|
pre_system | システム初期化直後(LoggerやConfig未使用) | IP制限・メンテナンスモードの設定など超初期の処理 |
post_system | 最終出力の直前(レスポンス確定前) | レスポンスへのヘッダー追加、ログ出力、出力内容の加工 |
pre_controller | コントローラメソッド実行直前 | 認証・認可処理、グローバル変数のセット、セッション検証 |
post_controller_constructor | コントローラのコンストラクタ直後 | コントローラの初期化ログ出力、パラメータの加工処理 |
post_controller | コントローラ処理の終了後(レスポンス処理前) | レスポンス加工、パフォーマンス計測、例外監視処理 |
display_override | 出力処理を完全に上書きする | HTML出力の置換、テンプレート全体のカスタマイズ(CLI非対応) |
cache_override | キャッシュ機構を上書きしたい時 | オリジナルのキャッシュ制御を使う必要があるとき |
database_query | 任意のSQLクエリ発行のたびに発火 | クエリログ出力、SQL監視ツールとの連携、監査用途 |
email_send | Email::send() 実行後 | メール送信ログ記録、外部APIへの連携通知など |
migrations_start | マイグレーションの処理開始時 | マイグレーション実行履歴の記録、メンテ通知の準備 |
migrations_end | マイグレーションの処理完了時 | 実行完了ログ、Slack通知などのアクション実行 |
seeds_start | シーダー処理開始 | テスト環境の初期化ログ出力、外部データ取り込み準備 |
seeds_end | シーダー処理完了 | シード完了通知、データ整合性チェックの実行 |
これらのイベントに対してフックを登録することで、アプリケーション全体の挙動を柔軟にカスタマイズできます。
実践:IPアドレスによるアクセス制限のフックを実装
以下に、特定のIP以外からのアクセスを拒否するシンプルなフックの例を紹介します。
app/Hooks/CheckIPHook.php
namespace App\Hooks;
class CheckIPHook
{
public static function check()
{
$allowedIPs = ['127.0.0.1', '192.168.0.1'];
$clientIP = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
if (!in_array($clientIP, $allowedIPs)) {
http_response_code(403);
exit('Access denied for IP: ' . $clientIP);
}
}
}
このフックをイベントに登録します:
app/Config/Events.php
use App\Hooks\CheckIPHook;
use CodeIgniter\Events\Events;
Events::on('pre_system', [CheckIPHook::class, 'check']);
このように登録することで、アプリケーション全体でIP制限が適用されます。
実践:すべてのレスポンスにカスタムヘッダーを追加
X-App-Version
という独自ヘッダーをレスポンスに追加する例です。
app/Hooks/AddHeaderHook.php
namespace App\Hooks;
class AddHeaderHook
{
public static function apply()
{
header('X-App-Version: 1.0.0');
}
}
app/Config/Events.php
use App\Hooks\AddHeaderHook;
Events::on('post_system', [AddHeaderHook::class, 'apply']);
応用:サービスプロバイダでのフック登録
イベント登録をEvents.php
にベタ書きするのではなく、サービスプロバイダを使うことで管理しやすくなります。
app/Providers/HookEventProvider.php
namespace App\Providers;
use CodeIgniter\Events\EventsInterface;
use CodeIgniter\Service\ServiceProvider;
use App\Hooks\CheckIPHook;
use App\Hooks\AddHeaderHook;
class HookEventProvider extends ServiceProvider
{
public function register(): void {}
public function boot(EventsInterface $events): void
{
$events->on('pre_system', [CheckIPHook::class, 'check']);
$events->on('post_system', [AddHeaderHook::class, 'apply']);
}
}
このファイルを作成後、Autoload.php
の$psr4
に追加すれば自動で読み込まれます。
注意点とベストプラクティス
注意点
pre_system
ではLoggerやConfigが使えません。- header系の出力処理は
post_system
以前に行う必要があります。 - 無限ループを招くような処理やエラーハンドリングには慎重な設計が必要です。
ベストプラクティス
- 責任の明確な単機能クラス設計(1フック = 1責務)
- 名前空間で機能ごとに整理する
- 環境(開発/本番)に応じた動作切り替えを意識する
- テスト用・開発用フックは明示的にON/OFF制御できるようにする
まとめ
CodeIgniter 4のHooks機能は、フレームワークの処理に柔軟に介入する強力な仕組みです。Filterのようなルーティングベースの仕組みよりも、より低レベルでの制御が可能なため、セキュリティ・ロギング・バージョン管理・外部連携などさまざまなニーズに対応できます。
うまく使えば、処理の重複を避けてDRYなコードを実現できますが、設計や依存の整理を怠るとトラブルの原因にもなります。責任範囲を明確にしたフック設計を心がけ、CodeIgniterの柔軟なイベントシステムを最大限活用していきましょう。
コメント