---
title: "CodeIgniter（コードイグナイター）とは？特徴・Laravelとの違いと4.7の使い方"
url: "https://www.issoh.co.jp/tech/details/7841/"
published: 2025-07-23
updated: 2026-10-24
categories: ["PHP"]
publisher: "株式会社一創"
---

# CodeIgniter（コードイグナイター）とは？特徴・Laravelとの違いと4.7の使い方

CodeIgniter（読み方は「コードイグナイター」）は、PHPで書かれた軽量なMVCフレームワークです。2026年10月時点の現行版は4.7.5（2026年10月9日リリース）で、動かすにはPHP 8.2以上が要ります。4.7.5にはファイルアップロード検証の迂回など6件の脆弱性への修正・緩和策が入っているので、4.7.4以前を使っているなら先に更新してください。ただしParserのテンプレートを利用者に編集させるアプリは、更新に加えて設定の変更が要ります。この記事では、現行版の要件と脆弱性修正、CodeIgniter 3との違い、Laravelとの選び方を整理したうえで、ローカルに4.7.5を入れてToDoアプリを動かした結果をもとに、既定値のつまずきどころを解説します。

## まとめ：CodeIgniterの現状と選びどころ

- CodeIgniterはMITライセンスのPHPフレームワークで、2006年にEllisLabが公開し、現在はCodeIgniter Foundationが管理しています。
- 現行は4.7.5です。4.7.0で最低要件がPHP 8.2に上がりました。保守されるのは最新版だけで、2026年10月9日に公開された6件の脆弱性も、修正・緩和策は4.7.5にしか入っていません。
- 4.7.4では、`shell.php.gif`という名前のGIF兼PHPファイルが画像のアップロード検証を通りました。4.7.5では同じファイルが拒否されます。
- CodeIgniter 3（最新3.1.13）は保守モードで、4系との後方互換はありません。3から4へは単純な更新ではなく、互換性のない部分の書き換えを伴う移行になります。
- 本番の依存パッケージはLaravel 13.38の77個に対して3個で、構成は軽量です。ただしPackagistの月間インストール数は約64分の1です。新規で案件や採用を重視するならLaravelを選び、既存のCodeIgniter資産を保守・改修する場面で選ぶのが現実的です。
- 新規プロジェクトでは、自動ルーティングもCSRF保護も既定で無効です。baseURLと合わせて、導入直後に設定を見直してください。

以下、現行版の位置づけ、脆弱性修正と更新手順、3系との違い、Laravelとの比較、導入から実装までの順に説明します。

## CodeIgniterの位置づけと現行バージョン

### 読み方・名前の意味・開発元とライセンス

表記は「CodeIgniter」で、カタカナでは「コードイグナイター」と書きます。英語の「igniter」は点火装置のことで、名前は「コード」と「点火装置」の組み合わせです。「codeignitor」「code igniter」は正式な表記ではなく、正式名は1語の「CodeIgniter」です。EllisLabが2006年2月28日に最初の公開版を出し、2014年にカナダのBritish Columbia Institute of Technology（BCIT）が引き継ぎました。2019年からはCodeIgniter Foundationが管理しています。ライセンスはMITで、商用利用が可能です。ソフトウェアの複製物や実質的な部分には、著作権表示と許諾文を含める必要があります。

### 4.7.5の動作要件と対応PHP

[公式の要件ページ](https://codeigniter.com/user%5Fguide/intro/requirements.html)によると、4.7系はPHP 8.2以上に加えて拡張モジュールの`intl`と`mbstring`が必須です。MySQLを使うなら`mysqlnd`、HTTPクライアント機能を使うなら`curl`が追加で必要です。

| PHPのバージョン | 必要なCodeIgniter | PHPのセキュリティサポート終了  |
| --------- | -------------- | ----------------- |
| PHP 8.5   | 4.7.0以上        | 2029年12月31日       |
| PHP 8.4   | 4.6.0以上        | 2028年12月31日       |
| PHP 8.3   | 4.4.4以上        | 2027年12月31日       |
| PHP 8.2   | 4.2.11以上       | 2026年12月31日       |
| PHP 8.1   | 4.7では対象外       | 2025年12月31日（終了済み） |

PHP側の終了日は[php.netのサポート版一覧](https://www.php.net/supported-versions.php)によります。PHP 8.2のセキュリティサポートは2026年12月31日で終わるので、8.2で動かしているなら年内に8.3以上へ上げる計画が必要です。なお、公式サイトのダウンロードページには2026年10月24日時点でも「PHP 8.1+ (including 8.4)」と書かれており、要件ページと食い違っています。判断するときは要件ページとPackagistの`require`（`php: ^8.2`）を基準にしてください。

### 4.7系のワーカーモードと互換性の変更

2026年2月1日の4.7.0では、最低PHPが8.2に上がったほか、FrankenPHPのワーカーモードに実験的に対応しました。`php spark worker:install`でCaddyfileとワーカー用のエントリポイントが生成され、`app/Config/WorkerMode.php`で、リクエストをまたいで保持するサービスを指定します。常駐型の実行モデルそのものは[FrankenPHPのワーカーモードの仕組み](/tech/details/7256/)で解説しています。ただし「実験的」の扱いなので、本番で使う前に、リクエスト間で状態が漏れないかを自分のアプリで確かめてください。

既存アプリに影響する変更もあります。バリデーションルール`regex_match`のプレースホルダーは`{{placeholder}}`の二重波括弧に変わり、`Entity::setAttributes()`や`Session::stop()`など非推奨だったメソッドは削除されました。4.6以前から上げる場合は、公式のアップグレードガイドを版ごとに順番に当てるのが安全です。

「CodeIgniter 5」は、2026年10月24日時点では公式リポジトリに5系のブランチがなく、次の開発ブランチは「4.8」です。5系をいつ出すかは、ブランチからは読み取れません。

## 4.7.5の脆弱性修正と更新手順

### 4.7.4・4.7.5で修正された脆弱性

2026年は、5月20日の4.7.3、7月7日の4.7.4、10月9日の4.7.5と、3回続けてセキュリティ修正が出ています。4.7.3では`ext_in`の拡張子検証の迂回（Critical）が直っており、3回ともアップロード検証の迂回の修正を含んでいます。下の表は4.7.4と4.7.5の分です。[GitHubのセキュリティアドバイザリ](https://github.com/codeigniter4/CodeIgniter4/security/advisories)の修正版欄はどれもその時点の最新版だけで、4.6系以前向けの修正版はありません。

| 公開日        | 深刻度      | 内容                                   | 修正版   |
| ---------- | -------- | ------------------------------------ | ----- |
| 2026-07-07 | Critical | is\_image・mime\_inの拡張子検証の迂回          | 4.7.4 |
| 2026-07-07 | Critical | deleteBatch()とwhere()の併用でSQLインジェクション | 4.7.4 |
| 2026-07-07 | High     | 利用者のファイル名でのmove()によるパストラバーサル         | 4.7.4 |
| 2026-07-07 | Medium   | isSecure()が偽装できる転送ヘッダを信用             | 4.7.4 |
| 2026-10-09 | Critical | 末尾のドットや途中のPHP拡張子で検証を迂回               | 4.7.5 |
| 2026-10-09 | High     | ビューのデータのキーで評価対象のテンプレートを上書き           | 4.7.5 |
| 2026-10-09 | High     | 利用者が編集できるParserテンプレートの条件式でPHPを実行     | 4.7.5 |
| 2026-10-09 | Medium   | Parserの自動エスケープを迂回するXSS               | 4.7.5 |
| 2026-10-09 | Medium   | 複数ファイルのアップロードで空の項目があると検証を省略          | 4.7.5 |
| 2026-10-09 | Medium   | CURLRequestの例外後に認証情報が次の宛先へ送られる       | 4.7.5 |

影響が大きいのは、アップロードを受け付けるアプリと、View Parser（`{name}`形式のテンプレート）を使うアプリです。[4.7.5の変更履歴](https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md)によると、Parserの条件式（`{if ...}`）は今もPHPとして評価されるのが既定の動作です。テンプレートを社外の人や権限の低い利用者に編集させるなら、新設の`Config\View::$restrictParserConditionals`を`true`にしてください。

### アップロード検証の挙動を4.7.4と4.7.5で比較

GIFのヘッダの後ろにPHPコードを付けたファイル（`file`コマンドの判定は`image/gif`）を用意し、ファイル名だけを変えて`uploaded[f]|is_image[f]|ext_in[f,gif]`の検証にかけました。4.7.4と4.7.5で、同じコントローラを動かした結果です。

| 送信したファイル名         | 4.7.4       | 4.7.5         |
| ----------------- | ----------- | ------------- |
| shell.php.gif     | 通過          | 拒否            |
| logo.php.gif      | 通過          | 拒否            |
| logo.gif.（末尾にドット） | 拒否（ext\_in） | 拒否（is\_image） |
| good.gif          | 通過          | 通過            |

4.7.4では、中身がPHPを含むファイルでも、名前が`.gif`で終わり先頭がGIFなら、3つのルールをすべて通りました。この名前のまま公開ディレクトリに保存し、Webサーバーが`.php`を含む名前をPHPとして実行する設定だと、アップロードしたファイルがそのまま[Webシェル](/tech/details/18314/)になります。4.7.5は`shell.php.gif`を「is not a valid, uploaded image file.」で拒否しました。ただし、無害な`logo.php.gif`も同じく拒否されます。[4.7.5のアップグレードガイド](https://codeigniter.com/user%5Fguide/installation/upgrade%5F475.html)はこれを破壊的変更として挙げ、利用者側でファイル名を`logo-php.gif`のように変えるよう案内しています。

更新しても、保存時の対策は別に要ります。`$file->getRandomName()`で生成した名前で保存し、アップロード先は`public/`の外（`writable/uploads`）に置くか、そのディレクトリでのスクリプト実行を止めてください。4.7.4では、利用者のファイル名のまま`move()`するとパストラバーサルになる脆弱性も直っています。利用者が付けたファイル名で公開ディレクトリに保存する作りは、検証ルールの穴が1つ見つかるだけで突破されます。

### composer updateでの更新とプロジェクトファイルの差分

App Starterで作ったプロジェクトの`composer.json`は`"codeigniter4/framework": "^4.7"`です。Composerの`^4.7`は4.7.0以上5.0.0未満を許すので、次のコマンドでその範囲の最新版（2026年10月24日時点では4.7.5）に上がります。4.8が出れば4.8へ上がるので、4.7系にとどめたいなら制約を`~4.7.0`に変えてください。

```
composer update codeigniter4/framework
php spark --version   # 「CodeIgniter v4.7.5」と表示されれば更新済み
```

更新されるのは`vendor/`の下のフレームワーク本体だけで、`app/`や`public/`の下のファイルは変わりません。4.7.5では`app/Config/View.php`に`$restrictParserConditionals`（既定値は`false`）が追加されたので、新しい`vendor/codeigniter4/framework/app/Config/View.php`と見比べて取り込みます。Parserで、値の中の`{name}`が後から展開される動作に頼っていたテンプレートは、4.7.5からプレースホルダーがそのまま表示されます。断片を先に描画してから`{! greeting !}`の形で渡すように書き換えてください。`{! !}`はエスケープを外す記法なので、渡すのは先の描画で入力値をエスケープし終えたHTMLだけにします。利用者の入力をそのまま渡すと、XSSを自分で作ることになります。

## CodeIgniter 3と4の違い

[公式のアップグレードガイド](https://codeigniter.com/user%5Fguide/installation/upgrade%5F4xx.html)は、冒頭で「CodeIgniter 4はフレームワークの書き直しで、後方互換性はない」と明言し、アップグレードではなく変換と考えるよう求めています。3系のコントローラやモデルは、そのままでは4系で動きません。

| 項目           | CodeIgniter 3     | CodeIgniter 4     |
| ------------ | ----------------- | ----------------- |
| 最新版          | 3.1.13（2022年3月3日） | 4.7.5（2026年10月9日） |
| 状態           | 保守（主にセキュリティ更新）    | 開発継続              |
| 名前空間         | なし                | あり（PSR-4）         |
| index.phpの位置 | プロジェクト直下          | public/           |
| アプリのフォルダ名    | application/      | app/              |
| 導入方法         | zip展開             | Composer（zipも可）   |
| CLI          | index.php経由で実行    | spark             |

公式ダウンロードページは、3系を「レガシー版」「保守中で、主にセキュリティ更新のみ」と説明しています。3系リポジトリ（bcit-ci/CodeIgniter）の最後のコミットは2024年3月20日で、それ以降は動きがありません。同じページの3系の説明は「PHP 5.6+」のままで、PHP 8系のどこまでで動くかは公式に示されていません。新しいPHPへ上げるたびに、自分で動作確認と修正を抱えることになります。3系のアプリを今後も数年使うなら、PHPを上げる時期に合わせて4系で作り直す計画を立てるべきです。

## Laravelとの違いと選び方

### CodeIgniter 4とLaravel 13の機能・依存パッケージ比較

依存パッケージとサイズは、2026年10月24日にCodeIgniterのApp StarterとLaravelの新規プロジェクト（`laravel/laravel`）をComposerで作り、`composer.lock`の本番用パッケージを数えて、開発用を除いてインストールした`vendor/`をmacOSの`du -sh`で測ったディスク使用量です。

| 項目              | CodeIgniter 4       | Laravel              |
| --------------- | ------------------- | -------------------- |
| 最新版（2026-10-24） | 4.7.5               | 13.38.0              |
| 必要なPHP          | 8.2以上               | 8.3以上                |
| 本番の依存パッケージ      | 3個                  | 77個                  |
| vendor（開発用を除く）  | 約5.5MiB・PHP 708ファイル | 約42MiB・PHP 6,035ファイル |
| DBアクセス          | Model＋Query Builder | Eloquent ORM         |
| リレーション定義        | 標準機能なし              | hasMany等で宣言          |
| 認証              | Shield（別パッケージ）      | スターターキット／Fortify     |
| CLI             | spark               | artisan              |

CodeIgniterの本番依存は本体と`laminas/laminas-escaper`、`psr/log`の3つだけです。更新のたびに確認する依存が少なく、脆弱性情報を追う範囲も狭く済みます。速度について「Laravelより何割速い」と書く記事もありますが、処理時間はアプリの中身とキャッシュ設定で大きく変わります。選定の根拠にするなら、自分のアプリの代表的な画面で測ってください。

機能面の最大の差はDB層です。CodeIgniterのModelは、テーブル1つに対するCRUDとバリデーションを受け持つだけで、テーブル同士の関連は自分でJOINを書きます。Laravelは、Eloquentでモデル間の関連を宣言でき、関連データの一括読み込みまで面倒を見ます（詳しくは[Laravel Eloquentのモデル定義とリレーション](/tech/details/17127/)）。画面数とテーブル数が多い業務システムほど、この差が工数に響きます。

### 利用規模の指標と案件・求人・転職先の探し方

[Packagistの統計](https://packagist.org/packages/codeigniter4/framework/stats)で月間インストール数（2026年10月24日8時47分〈日本時間〉に3パッケージを続けて取得）を見ると、`codeigniter4/framework`が317,032、`laravel/framework`が20,266,121で、約64倍の差があります。CakePHP（551,769）と比べても約6割です。GitHubのスター数は、4系のリポジトリが5,989、更新の止まった3系のリポジトリが18,148で、3系の方が多い状態です。比較記事で見かける「スター約1.8万」は3系の数字です。

この比率はパッケージのインストール回数の差であり、日本の案件数や求人数の比率ではありません。案件や転職先を探すときは、求人媒体で希望条件に合う募集を実際に数えて比べてください。そのうえで、CodeIgniterの経験だけを売りにするより、3系・4系の保守案件を入口にしてLaravelも扱えるようにしておくと、応募できる募集の幅が広がります。Laravel側の需要とサポート期限は[Laravelの将来性を2026年のデータで判断した記事](/tech/details/5469/)にまとめています。

### CodeIgniterを選ぶ場面・選ぶべきでない場面

CodeIgniterが向くのは、既存のCodeIgniterアプリを保守・拡張する場合と、テーブル同士の関連が少なくJOINを自分で書いて済む社内ツールやAPIを、Shieldと標準機能の範囲で少人数で作り、保守もその体制で続けられる場合です。設定は`app/Config`の下にクラス単位で平たく並び（4.7.5の新規プロジェクトで41ファイル）、ルートからコントローラ、モデルまでの処理を、コードを読んで追えます。3系のまま止まっているアプリの保守や4系への移行を外部に任せるなら、[システムの保守運用・内製化支援](/service/system/maintenance/)のように、改修と運用を続けて引き受ける形が合います。

新規のSaaSや大規模開発では、必要な周辺機能を既存パッケージで賄えず、CodeIgniterの保守担当者も確保できないなら、採用を避けるべきです。公式パッケージとしては認証のShield（v1.4.1）とキューのQueue（v1.0.1）がありますが、通知や管理画面の生成などはLaravelに比べて既製品が少なく、足りない部分は自作して保守し続けることになります。必要な機能を一覧にし、既存のパッケージで埋まるかを先に確かめてください。フレームワーク選定の全体像は[PHP開発の全体像とフレームワーク選定](/tech/details/1316/)で、新興のPHPフレームワークとの比較は[TempestとLaravel・Symfonyの違い](/tech/details/8418/)で扱っています。

## CodeIgniter 4のインストールと初期設定

### Composerでの導入と開発サーバーの起動

公式が推奨するのはComposerでApp Starterを取得する方法です。2026年10月24日にPHP 8.5.8の環境で次のコマンドを実行すると、4.7.5が入りました。

```
composer create-project codeigniter4/appstarter myapp
cd myapp
php spark serve --port 8091
```

`php spark serve`はPHP内蔵サーバーを使う開発用サーバーで、既定のポートは8080です。使用中なら自動で次の番号を試し、`--port 8091`のように指定もできます。本番ではApacheやNginxのドキュメントルートを`public/`に向けます。プロジェクト直下を公開すると、`.env`や`writable/`が外から読まれる危険があります。

### .envとbaseURLの設定

App Starterには`.env`が同梱されておらず、見本の`env`ファイルを`.env`にコピーして使います。`CI_ENVIRONMENT`を設定しないと環境は`production`になり、エラー詳細もデバッグツールバーも出ません。

```
cp env .env

# .env に追記
CI_ENVIRONMENT = development
app.baseURL = 'http://localhost:8091/'
app.indexPage = ''
```

見落としやすいのが`app/Config/App.php`の既定値です。`baseURL`は`http://localhost:8080/`、`indexPage`は`index.php`になっています。別のポートで起動したまま`redirect()->to('/tasks')`を実行すると、リダイレクト先は`http://localhost:8080/index.php/tasks`になりました。URLを生成する処理はすべてbaseURLを基準にするので、ポートやドメインを変えたら最初にここを合わせ、mod\_rewriteを使うなら`indexPage`を空にします。

### ディレクトリ構成と各フォルダの役割

Composerで入れた場合、プロジェクト直下は次の構成になります。フレームワーク本体（system）は`vendor/codeigniter4/framework/system`に入り、自分では編集しません。

| フォルダ      | 役割                              |
| --------- | ------------------------------- |
| app/      | Controllers・Models・Views・Config |
| public/   | index.phpと静的ファイル（公開する唯一のフォルダ）   |
| writable/ | ログ・キャッシュ・セッション・アップロード           |
| tests/    | PHPUnitのテスト                     |
| vendor/   | Composerの依存（systemを含む）          |

`writable/`はWebサーバーの実行ユーザーが書き込める権限にしておきます。ここに書けないと、ログやセッションの保存で落ちます。

## ルーティングとMVCの実装例（ToDoアプリ）

ここからは、SQLiteを使ったToDoアプリを4.7.5で動かした手順です。PHPのSQLite3拡張が要るので、`php -m | grep -i sqlite3`で有効になっているかを先に確かめてください。`.env`に`database.default.DBDriver = SQLite3`と`database.default.database = ci.db`を書くと、DBファイルは`writable/`の下に作られます。

### ルート定義と自動ルーティングの既定値

4系の新規プロジェクトでは自動ルーティングが無効（`app/Config/Routing.php`の`$autoRoute = false`）で、URLは`app/Config/Routes.php`に書いたものだけが通ります。

```
$routes->get('tasks', 'Tasks::index');
$routes->post('tasks', 'Tasks::create');
```

この状態で`/tasks/index`にアクセスすると404になりました。3系のように「コントローラ名/メソッド名」で自動的に繋がると思って移行すると、ここで止まります。定義したルートは`php spark routes`で一覧でき、適用されるフィルターも同時に表示されます。自動ルーティングを使いたい場合は、旧方式ではなく、公式が推奨する改良版（Auto Routing Improved）を有効にします。

### マイグレーションとモデルの作成

雛形は`php spark make:migration CreateTasks`と`php spark make:model TaskModel`で作れます。生成されたマイグレーション（`app/Database/Migrations`の下）に、テーブル定義を書きます。

```
<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class CreateTasks extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id'         => ['type' => 'INTEGER', 'unsigned' => true, 'auto_increment' => true],
            'title'      => ['type' => 'VARCHAR', 'constraint' => 100],
            'done'       => ['type' => 'TINYINT', 'constraint' => 1, 'default' => 0],
            'created_at' => ['type' => 'DATETIME', 'null' => true],
            'updated_at' => ['type' => 'DATETIME', 'null' => true],
        ]);
        $this->forge->addKey('id', true);
        $this->forge->createTable('tasks');
    }

    public function down()
    {
        $this->forge->dropTable('tasks');
    }
}
```

`php spark migrate`でテーブルを作ってから、モデルを書きます。モデルは次の数行で動きます。

```
<?php

namespace App\Models;

use CodeIgniter\Model;

class TaskModel extends Model
{
    protected $table         = 'tasks';
    protected $allowedFields = ['title', 'done'];
    protected $useTimestamps = true;

    protected $validationRules = [
        'title' => 'required|max_length[100]',
    ];
}
```

`$allowedFields`は一括代入の防止策で、ここに無い列は`insert()`や`update()`で黙って捨てられます。`['title' => 'ok', 'id' => 999, 'bogus' => 1]`を`insert()`すると、`id`は999ではなく自動採番の値になり、`bogus`は無視されました。主キーは`$allowedFields`に入れないのが公式の指示です。空のタイトルで`insert()`すると`false`が返り、`errors()`に「The title field is required.」が入ります。

### コントローラとビューの連携

```
<?php

namespace App\Controllers;

use App\Models\TaskModel;

class Tasks extends BaseController
{
    public function index()
    {
        $tasks = model(TaskModel::class)->orderBy('id', 'DESC')->findAll();

        return view('tasks/index', ['tasks' => $tasks]);
    }

    public function create()
    {
        $model = model(TaskModel::class);

        if (! $model->insert(['title' => $this->request->getPost('title')])) {
            return redirect()->back()->withInput()->with('errors', $model->errors());
        }

        return redirect()->to('/tasks');
    }
}
```

ビュー（`app/Views/tasks/index.php`）では、出力を必ず`esc()`で囲みます。`old()`は既定でエスケープ済みの値を返すので、`esc()`で包む必要はありません。送信先は`site_url()`で生成すると、baseURLの設定が反映され、サブディレクトリに置いても正しいURLになります。フォームには`csrf_field()`を入れておきます。次章でCSRF保護を有効にしたときに、このトークンが必要になるためです。

```
<?php foreach (session('errors') ?? [] as $error): ?>
    <p><?= esc($error) ?></p>
<?php endforeach ?>

<form method="post" action="<?= esc(site_url('tasks'), 'attr') ?>">
    <?= csrf_field() ?>
    <input name="title" value="<?= old('title', '', 'attr') ?>">
    <button>追加</button>
</form>

<ul>
<?php foreach ($tasks as $task): ?>
    <li><?= esc($task['title']) ?></li>
<?php endforeach ?>
</ul>
```

## クエリビルダーとトランザクション

JOINや集計などモデルで書きにくい処理は、Query Builderで組み立てます。次のコードを4.7.5で実行し、`getLastQuery()`で生成されたSQLを確かめると、LIKEの値は`LIKE '%牛%' ESCAPE '!'`の形でエスケープされていました。

```
$db = db_connect();

$rows = $db->table('tasks')
    ->select('id, title')
    ->where('done', 0)
    ->like('title', '牛')
    ->orderBy('id', 'DESC')
    ->get()
    ->getResultArray();

$db->transStart();
$db->table('tasks')->insert(['title' => '買い物']);
$db->table('tasks')->where('id', 1)->update(['done' => 1]);
$db->transComplete();

if ($db->transStatus() === false) {
    // ロールバック済み。ログを残して利用者にエラーを返す
}
```

`transStart()`から`transComplete()`の間でクエリが1つでも失敗すると、全体が自動でロールバックされます。存在しないテーブルへのINSERTを混ぜて試すと、`transStatus()`は`false`を返し、同じトランザクションで入れた行も残りませんでした。条件を付け忘れたときの挙動は、メソッドによって違います。`where()`なしの`delete()`は`Deletes are not allowed unless they contain a "where" or "like" clause.`という例外で止まり、行は残りました。一方、`where()`なしの`update()`はそのまま全行を更新しました。`update()`を書くときは、条件を先に書く習慣をつけてください。

## CSRF保護と認証の設定

### CSRFフィルターの有効化

4.7.5の`app/Config/Filters.php`では、`$globals`の`'csrf'`がコメントアウトされていて、CSRF保護は無効です。そのままだと、トークンなしのPOSTでもデータが保存されます。コメントを外すとフィルターが全体に適用され、POST・PUT・PATCH・DELETEリクエストでトークンが検証されます（GETは検証の対象外です）。

あわせて、`app/Config/Security.php`の`$csrfProtection`を、既定の`'cookie'`から`'session'`に変えます。公式ドキュメントは、Cookie方式では同一サイトからの攻撃を防げないとして、セッションを使うアプリにはセッション方式を指定するよう警告しています。前章の例は`old()`と`withInput()`でセッションを使っています。Cookie方式のままリダイレクトする場合は、再生成されたトークンを`withCookie()`で送り直す必要があります。

```
public array $globals = [
    'before' => [
        'csrf',
    ],
    'after' => [],
];
```

セッション方式で有効にしたあと、トークンなしでPOSTすると403が返りました。`csrf_field()`のトークンを付けたPOSTは保存され、入力エラーで戻ったあとの再送信も通りました。なお、失敗時の挙動は環境で変わります。`app/Config/Security.php`の`$redirect`の既定値は`ENVIRONMENT === 'production'`で、本番では、通常のフォーム送信は403ではなく元のページへリダイレクトされます。AJAXのリクエスト（`X-Requested-With: XMLHttpRequest`付き）は本番でもリダイレクトされず、`SecurityException`になります。本番で「送信しても何も起きない」と問い合わせが来たら、まずCSRFの失敗を疑ってください。

### Shieldによるログイン機能の追加

本体にログイン機能はなく、公式の認証・認可パッケージ「CodeIgniter Shield」（最新v1.4.1、2026年8月18日）を`composer require codeigniter4/shield`で追加します。セッション認証とアクセストークン、グループと権限の管理まで入っています。認証を自作したり非公式のライブラリを探したりする前に、まずShieldで要件を満たせるかを確認してください。あわせて[PHPStanによる静的解析](/tech/details/12338/)をCIに入れておくと、型の不整合を実行前に見つけられます。

## よくある質問

### CodeIgniterの読み方と意味は？

「コードイグナイター」と読みます。「igniter」は英語で点火装置のことです。略称として「CI」「CI4」も使われ、4系を指すときは「CI4」と書くのが一般的です。

### CodeIgniterとLaravelの違いは？

CodeIgniterは本番の依存パッケージが3個と少なく、設定も読みやすい一方、リレーションを宣言できるORMや周辺パッケージはLaravelより少なめです。Laravelは機能と利用者数が多く、Packagistの月間インストール数は約64倍です。既存資産の保守ならCodeIgniter、新規で機能と人材を重視するならLaravelが目安です。

### CodeIgniter 5はリリースされていますか？

2026年10月24日時点ではリリースされていません。公式リポジトリに5系のブランチはなく、次の開発ブランチは4.8です。

### CodeIgniterにORMはありますか？

EloquentやDoctrineのような、リレーションを宣言できるORMはありません。テーブル単位のModelと、行をオブジェクトとして扱うEntity、SQLを組み立てるQuery Builderの組み合わせで扱います。関連の多いデータ構造なら、Doctrineを別途入れるか、Laravelを検討してください。

### CodeIgniter 3はまだ使えますか？

動かすことはできますが、最新版は2022年3月の3.1.13で、公式の位置づけも「主にセキュリティ更新のみのレガシー版」です。新規開発には使わず、既存アプリはPHPの更新時期に合わせて4系へ移すのが現実的です。

## 関連記事

- [PHP開発の始め方｜環境構築・フレームワーク選定・システム開発の進め方【PHP 8.5対応】](/tech/details/1316/)
- [Laravelの将来性を2026年のデータで判断する｜サポート期限・求人単価・AI対応](/tech/details/5469/)
- [Tempestとは？PHPフレームワークの導入手順とLaravel・Symfonyとの違い【v3.19.2実測】](/tech/details/8418/)
- [Laravel Eloquentとは｜モデル定義・リレーション・eager loadingの基礎とクエリビルダの使い分け](/tech/details/17127/)
- [FrankenPHPとは？PHP-FPMとの違い・ワーカーモードの仕組みと導入手順【v1.12対応】](/tech/details/7256/)

---

出典: [CodeIgniter（コードイグナイター）とは？特徴・Laravelとの違いと4.7の使い方](<https://www.issoh.co.jp/tech/details/7841/>)（株式会社一創）
