コントローラ

コントローラはアプリケーションの心臓部であり、HTTP リクエストがどのように処理されるべきかを決定する部分です。

コントローラとは何か?

コントローラは単純なクラスファイルですが、ある程度 URI に関連した名前を持ちます。

次の URI を考えてみましょう:

example.com/index.php/blog/

上の例では、CodeIgniter は Blog.php を探し出し、読み込もうとします。

コントローラの名前と URI の第1セグメントが一致するとき、それは読み込まれます。

やってみましょう: Hello World!

シンプルなコントローラを作ってみましょう。動作するところを見られます。テキストエディタを使い、Blog.php というファイルを作成し、次のコードを入力してください:

<?php namespace App\Controllers;

use CodeIgniter\Controller;

class Blog extends Controller
{
        public function index()
        {
                echo 'Hello World!';
        }
}

Then save the file to your /app/Controllers/ directory.

重要

ファイル 'Blog.php' は大文字の 'B' でなくてはなりません。

さて、次のような URL でサイトを表示しましょう:

example.com/index.php/blog

うまくできたなら、これが見られます:

Hello World!

重要

クラス名は大文字で始めなければなりません。

これは正しいものです:

<?php namespace App\Controllers;

use CodeIgniter\Controller;

class Blog extends Controller {

}

これは正しく ありません

<?php namespace App\Controllers;

use CodeIgniter\Controller;

class blog extends Controller {

}

また、常に親コントローラクラスを継承していることを確認してください。その全メソッドを継承します。

メソッド

In the above example, the method name is index(). "index" メソッドは URL の 第2セグメント がないとき、いつもデフォルトで呼ばれます。"Hello World" メッセージを表示するもう一つの方法はこれです:

example.com/index.php/blog/index/

URI の第2セグメントはコントローラのどのメソッドを呼ぶかを決定します。

試してみましょう。コントローラに新しいメソッドを追加します:

<?php namespace App\Controllers;

use CodeIgniter\Controller;

class Blog extends Controller
{

        public function index()
        {
                echo 'Hello World!';
        }

        public function comments()
        {
                echo 'これを見て!';
        }
}

さて、次の URL を読み込んで comments メソッドを見てみましょう:

example.com/index.php/blog/comments/

新しいメッセージを見れたはずです。

メソッドに URI セグメントを渡す

URI に2つより多くのセグメントが渡されたなら、それらはメソッドに引数として渡されます。

例として、次のような URI があったとします:

example.com/index.php/products/shoes/sandals/123

メソッドには第3・第4セグメント("sandals" と "123")が渡されます:

<?php namespace App\Controllers;

use CodeIgniter\Controller;

class Products extends Controller
{

        public function shoes($sandals, $id)
        {
                echo $sandals;
                echo $id;
        }
}

重要

もし URI ルーティング 機能を使っているなら、メソッドに渡されるセグメントは再ルーティングされたものになります。

デフォルトコントローラを定義する

CodeIgniter には URI にコントローラが与えられなかった場合にロードするデフォルトを指定することができます。サイトのルート URL がリクエストされたときだけ使用されます。 To specify a default controller, open your app/Config/Routes.php file and set this variable:

$routes->setDefaultController('Blog');

Where 'Blog' is the name of the controller class you want to be used. これで URI セグメントに何も指定せずに index.php を読み込んだなら、"Hello World" メッセージがデフォルトで表示されるでしょう。

より詳しくは、URI ルーティング ドキュメントの "ルーティングの設定オプション" を参照してください。

呼び出しメソッドの再マッピング

上にも書きましたように、URI の第2セグメントはたいていコントローラのメソッドとして判定されます。CodeIgniter では _remap() メソッドを使ってこの動作をオーバーライドすることができます:

public function _remap()
{
        // 何かしらのコードをここに……
}

重要

コントローラが _remap() というメソッドを持っていたなら、URI が何であれこれは 常に 呼び出されます。これは URI から呼び出されるメソッドを決定するという通常の振る舞いをオーバーライドし、独自のメソッドルーティングルールを定義できます。

オーバーライドされた呼び出しメソッド(典型的には URI の第2セグメント)は _remap() メソッドの引数として渡されます:

public function _remap($method)
{
        if ($method === 'some_method')
        {
                $this->$method();
        }
        else
        {
                $this->default_method();
        }
}

メソッド名の後にある他の追加のセグメントも _remap() に渡されます。これらのパラメータは CodeIgniter のデフォルトの振る舞いに釣り合わせるためメソッドに渡すことができます。

例:

public function _remap($method, ...$params)
{
        $method = 'process_'.$method;
        if (method_exists($this, $method))
        {
                return $this->$method(...$params);
        }
        throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}

プライベートメソッド

In some cases, you may want certain methods hidden from public access. そのためには、単にメソッドを private または protected として定義してください。URI リクエスト経由では呼び出されなくなります。例として、次のようなメソッドがあるならば:

protected function utility()
{
        // いくらかのコード
}

URL 経由でアクセスしようとしても、これは動きません:

example.com/index.php/blog/utility/

コントローラをサブディレクトリに整理する

もし大型アプリケーションを作っているなら、コントローラをサブディレクトリに入れて、階層的な整理ないし構造化したいことでしょう。CodeIgniter はそうすることができます。

Simply create sub-directories under the main app/Controllers/ one and place your controller classes within them.

注釈

この機能を使ったら、URI の第1セグメントにはフォルダ名を指定しなければなりません。例えば、こんなコントローラを持っているとしましょう:

app/Controllers/products/Shoes.php

上のコントローラを呼ぶには、URI は次のようなものになります:

example.com/index.php/products/shoes/show/123

それぞれのサブディレクトリにはデフォルトコントローラを持たせられます。URI にサブディレクトリ だけ が指定されているときに呼ばれます。Simply put a controller in there that matches the name of your 'default_controller' as specified in your app/Config/Routes.php file.

また、CodeIgniter では URI ルーティング 機能を使用することで URI の再マッピングが可能です。

持っているプロパティ

すべてのコントローラは CodeIgniter\Controller クラスを継承する必要があります。 このクラスはすべてのコントローラで有効になるいくつかの機能を提供します。

Request Object

The application's main Request Instance is always available as a class property, $this->request.

Response Object

The application's main Response Instance is always available as a class property, $this->response.

Logger Object

ロガー クラスのインスタンスはクラスのプロパティ $this->logger として利用可能です。

forceHTTPS

メソッドにHTTPS 経由のアクセスを強制するための便利なメソッドが、すべてのコントローラ内で利用可能です:

if (!$this->request->isSecure())
{
        $this->forceHTTPS();
}

デフォルトでは、モダンなブラウザでは HTTP Strict Transport Security ヘッダをサポートしていますが、この呼び出しはブラウザに non-HTTPS 呼び出しから HTTPS 呼び出しへ強制するのを1年間としています。第1引数でその期間(秒単位)を変更できます:

if (!$this->request->isSecure())
{
        $this->forceHTTPS(31536000);    // 1年
}

注釈

多くの 時間ベースの定数 が常に利用可能です。年、月、そのほかも。

ヘルパ

ヘルパファイルの配列をクラスのプロパティとして定義できます。コントローラが読み込まれればいつでも、そのヘルパファイルは自動的にメモリに読み込まれます。そのため、コントローラ内のどこでもそのメソッドを利用できます:

namespace App\Controllers;
use CodeIgniter\Controller;

class MyController extends Controller
{
        protected $helpers = ['url', 'form'];
}

Validating data

The controller also provides a convenience method to make validating data a little simpler, validate() that takes an array of rules to test against as the first parameter, and, optionally, an array of custom error messages to display if the items don't pass. Internally, this uses the controller's $this->request instance to get the data through. バリデーションライブラリドキュメント にはルールとメッセージの配列の形式と利用可能なルールについて、詳細が書かれています:

public function updateUser(int $userID)
{
    if (!$this->validate([
        'email' => "required|is_unique[users.email,id,{$userID}]",
        'name'  => 'required|alpha_numeric_spaces'
    ]))
    {
        return view('users/update', [
            'errors' => $this->validator->getErrors()
        ]);
    }

    // 成功したときに行うことをここに
}

もしルールを設定ファイルに保存しておくのがより簡便と考えるなら、$rules 配列をグループ名に置き換え、Config\Validation.php に定義することができます:

public function updateUser(int $userID)
{
    if (!$this->validate('userRules'))
    {
        return view('users/update', [
            'errors' => $this->validator->getErrors()
        ]);
    }

    // 成功したときに行うことをここに
}

注釈

また、バリデーションはモデルで自動処理させることもできます。Where you handle validation is up to you, and you will find that some situations are simpler in the controller than then model, and vice versa.

これでおしまいです!

これが、かいつまんでですが、コントローラについて知るべきことのすべてです。