カテゴリ: CodeIgniter 更新日: 2026/04/24

CodeIgniterのコントローラを肥大化させない!初心者でもわかる「スリムな設計」のコツ

CodeIgniterのコントローラを肥大化させない設計のコツ
CodeIgniterのコントローラを肥大化させない設計のコツ

先生と生徒の会話形式で理解しよう

生徒

「CodeIgniterでアプリを作っているのですが、コントローラのファイルがどんどん長くなって、どこに何が書いてあるか分からなくなってしまいました…。」

先生

「それはプログラミング初心者が最初によくぶつかる壁ですね。コントローラに何でもかんでも書きすぎてしまうことを『肥大化』と呼びます。」

生徒

「どうすればスッキリ整理できるんでしょうか?パソコンも初心者なので、簡単な例えで教えてほしいです!」

先生

「分かりました。料理店に例えると、コントローラは『注文を受ける店員さん』です。店員さんが料理まで作り始めると大変ですよね?役割を分担するコツを学んでいきましょう!」

1. コントローラとは?役割を再確認しよう

1. コントローラとは?役割を再確認しよう
1. コントローラとは?役割を再確認しよう

PHPの人気フレームワークであるCodeIgniter(コードイグナイター)には、「MVC(エムブイシー)」という仕組みがあります。これは、プログラムの役割を3つのチームに分ける考え方です。

  • M(モデル):データの処理担当(料理を作る人)
  • V(ビュー):見た目の表示担当(お皿や盛り付け)
  • C(コントローラ):司令塔・つなぎ役担当(注文を受ける店員さん)

初心者のうちは、この「コントローラ」の中に、計算式やデータベースとのやり取りをすべて書いてしまいがちです。しかし、本来のコントローラの仕事は「ユーザーからの入力を受け取って、モデルにお願いして、結果をビューに渡す」という橋渡しだけにするのが理想です。

2. なぜコントローラが太ってしまうのか?(肥大化の原因)

2. なぜコントローラが太ってしまうのか?(肥大化の原因)
2. なぜコントローラが太ってしまうのか?(肥大化の原因)

プログラムが「肥大化」する、つまりコードの行数が何百行、何千行と増えてしまう最大の原因は、「コントローラに計算や複雑なルールを書きすぎている」ことです。

例えば、ブログの記事を投稿する機能を考えてみましょう。 「文字数は足りているか?」「禁止用語は入っていないか?」「画像は正しい形式か?」といったチェック(バリデーションといいます)や、「データベースへの保存」「完了メールの送信」といった作業をすべてコントローラに書くと、あっという間にファイルがパンパンになってしまいます。これを防ぐためには、「ロジック(仕組み)」を外に追い出す必要があります。

3. ロジックをモデル(Model)へ移動させよう

3. ロジックをモデル(Model)へ移動させよう
3. ロジックをモデル(Model)へ移動させよう

CodeIgniterにおいて、データベースに関わる計算や処理は、できるだけ「Model(モデル)」に書くようにしましょう。これを「Fat Model, Skinny Controller(太ったモデル、痩せたコントローラ)」と呼び、良い設計の合言葉とされています。

以下に、悪い例(コントローラが太っている状態)のイメージを紹介します。


// 悪い例:コントローラの中で全部やってしまっている
public function register() {
    $name = $this->request->getPost('name');
    
    // データベースへの保存処理をコントローラに直接書くと肥大化の原因に!
    $db = \Config\Database::connect();
    $sql = "INSERT INTO users (name) VALUES (" . $db->escape($name) . ")";
    $db->query($sql);

    return view('success_view');
}

このようにコントローラに直接データベースの操作を書くのではなく、専用のモデルを作って、そちらに「保存してね」と頼むように書き換えるのがスリム化への第一歩です。

4. バリデーション(入力チェック)を外部化する

4. バリデーション(入力チェック)を外部化する
4. バリデーション(入力チェック)を外部化する

「名前が未入力ではないか?」「メールアドレスの形式が正しいか?」といったチェックをコントローラの中に書くと、同じようなコードが何度も登場してしまいます。CodeIgniterには、これらを自動で処理する機能があります。

チェックのルールを別ファイル(設定ファイル)にまとめたり、専用のクラスを作ったりすることで、コントローラの記述をたった一行に減らすことができます。店員さんが「お客様の注文が正しいか」をいちいち細かくチェックするマニュアルを暗記するのではなく、チェックリスト(外部ファイル)を見て判断するイメージです。

5. 共通の処理は「ライブラリ」や「ヘルパー」を活用

5. 共通の処理は「ライブラリ」や「ヘルパー」を活用
5. 共通の処理は「ライブラリ」や「ヘルパー」を活用

どの画面でも使うような共通の処理(例:日付の形式を変換する、ログインしているか確認するなど)は、コントローラに書くのではなく、「ヘルパー(Helper)」「ライブラリ(Library)」という場所にまとめます。

例えば、消費税の計算をする処理が必要な場合、それをコントローラに書くのではなく、以下のように共通の関数として定義しておくと便利です。


// 共通ヘルパーのイメージ
function calculate_tax($price) {
    // 10%の消費税を計算して返す
    return $price * 1.1;
}

これを用意しておけば、どのコントローラからも calculate_tax(1000) と呼び出すだけで済むようになり、コントローラが非常にスッキリします。

6. 条件分岐をシンプルにするテクニック

6. 条件分岐をシンプルにするテクニック
6. 条件分岐をシンプルにするテクニック

コントローラの中で「もしAならこれ、Bならこれ、Cなら…」と if 文が重なりまくると、読むのが嫌になってしまいます。そんなときは、複雑な条件判定そのものをモデル側に持たせるか、早期リターンという手法を使います。

早期リターンとは、ダメな場合はすぐに処理を終わらせる書き方です。これにより、コードの階層(インデント)が深くならず、読みやすくなります。


// 早期リターンを使ったスッキリした書き方
public function update_profile() {
    // ログインしていなければ、即座に終了してログイン画面へ
    if (!$this->is_logged_in()) {
        return redirect()->to('/login');
    }

    // ここからはログインしている人だけの処理(ifのネストが深くならない!)
    $this->userModel->save($this->request->getPost());
    return view('profile_updated');
}

7. サービス層(Service Layer)の導入を検討する

7. サービス層(Service Layer)の導入を検討する
7. サービス層(Service Layer)の導入を検討する

さらに大規模なアプリを作るようになると、モデルだけでも足りなくなることがあります。そんなときは「サービス(Service)」という新しい担当者を雇うことを検討しましょう。

例えば「商品を注文する」という動作には、「在庫を減らす」「ポイントを付与する」「注文確認メールを送る」といった複数の作業が伴います。これらを一つの「注文サービス」というクラスにまとめておけば、コントローラは「注文サービスを実行して!」と一言命じるだけでよくなります。


// サービス層を使ったスリムなコントローラの例
public function checkout() {
    $orderService = new OrderService();
    
    // 複雑な一連の処理はサービスの中で実行される
    $result = $orderService->processOrder($this->request->getPost());

    if ($result) {
        return view('order_success');
    } else {
        return view('order_error');
    }
}

8. 良い設計は「変更に強い」アプリを作る

8. 良い設計は「変更に強い」アプリを作る
8. 良い設計は「変更に強い」アプリを作る

なぜここまでしてコントローラをスリムにする必要があるのでしょうか?それは、「後からの修正が楽になるから」です。プログラムの世界では、一度作って終わりということはありません。「やっぱり消費税を15%にしたい」「メールの文面を変えたい」といった変更が必ず発生します。

その際、コントローラがパンパンだと、どこを直せばいいか分からず、一箇所直すと別の場所が壊れるという悪夢が起こります。役割をしっかり分けておけば、モデルだけを直せばすべての画面に反映されるといった、スマートな管理が可能になります。初心者のうちから「店員さん(コントローラ)に無理をさせない」設計を意識して、楽しく開発を続けていきましょう!

カテゴリの一覧へ
新着記事
New2
Symfony
SymfonyでAPI向けにカスタムエラーメッセージを返す方法を解説!初心者でも安心のバリデーション基礎
New3
Symfony
Symfonyの動的フォームフィールド追加・削除を完全ガイド!初心者でもわかるフォーム操作入門
New4
Laravel
LaravelのMailableクラスの使い方を完全解説!初心者でもできるメール送信管理
人気記事
No.1
Java&Spring記事人気No1
CodeIgniter
CodeIgniterのセッション管理を徹底解説!値を保存・取得する基本操作
No.2
Java&Spring記事人気No2
Laravel
Laravelのnow()・today()関数の使い方完全ガイド!初心者でもわかる日時処理と日付操作
No.3
Java&Spring記事人気No3
Symfony
Symfony Twig入門|条件分岐とループをやさしく理解するテンプレート活用術
No.4
Java&Spring記事人気No4
Laravel
Laravelのabort()関数でエラーを返す方法!初心者向け完全ガイド
No.5
Java&Spring記事人気No5
Laravel
Laravelの日付バリデーションの使い方を完全解説!初心者でも安心の丁寧ガイド
No.6
Java&Spring記事人気No6
Laravel
Laravelのインストール方法まとめ!ComposerとLaravel Installerの使い方
No.7
Java&Spring記事人気No7
Laravel
Laravelの@eachディレクティブで簡単に繰り返しテンプレートを表示する方法
No.8
Java&Spring記事人気No8
Laravel
LaravelのThrottleミドルウェアでアクセス制限を実装する方法!初心者向け解説