コントローラ¶
コントローラはアプリケーションの心臓部であり、HTTP リクエストがどのように処理されるべきかを決定する部分です。
Page Contents
コントローラとは何か?¶
コントローラは単純なクラスファイルですが、ある程度 URI に関連した名前を持ちます。
次の URI を考えてみましょう:
example.com/index.php/blog/
上の例では、CodeIgniter は Blog.php を探し出し、読み込もうとします。
コントローラの名前と URI の第1セグメントが一致するとき、それは読み込まれます。
やってみましょう: Hello World!¶
シンプルなコントローラを作ってみましょう。動作するところを見られます。テキストエディタを使い、Blog.php というファイルを作成し、次のコードを入力してください:
<?php
class Blog extends \CodeIgniter\Controller
{
public function index()
{
echo 'Hello World!';
}
}
/application/Controllers/ ディレクトリに保存してください。
重要
ファイル 'Blog.php' は大文字の 'B' でなくてはなりません。
さて、次のような URL でサイトを表示しましょう:
example.com/index.php/blog
うまくできたなら、これが見られます:
Hello World!
重要
クラス名は大文字で始めなければなりません。
これは正しいものです:
<?php
class Blog extends \CodeIgniter\Controller {
}
これは正しく ありません
<?php
class blog extends \CodeIgniter\Controller {
}
また、常に親コントローラクラスを継承していることを確認してください。その全メソッドを継承します。
メソッド¶
上の例では、メソッド名は index()
です。"index" メソッドは URL の 第2セグメント がないとき、いつもデフォルトで呼ばれます。"Hello World" メッセージを表示するもう一つの方法はこれです:
example.com/index.php/blog/index/
URI の第2セグメントはコントローラのどのメソッドを呼ぶかを決定します。
試してみましょう。コントローラに新しいメソッドを追加します:
<?php
class Blog extends \CodeIgniter\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
class Products extends \CodeIgniter\Controller {
public function shoes($sandals, $id)
{
echo $sandals;
echo $id;
}
}
重要
もし URI ルーティング 機能を使っているなら、メソッドに渡されるセグメントは再ルーティングされたものになります。
デフォルトコントローラを定義する¶
CodeIgniter には URI にコントローラが与えられなかった場合にロードするデフォルトを指定することができます。サイトのルート URL がリクエストされたときだけ使用されます。 デフォルトコントローラを指定するには、application/Config/Routes.php ファイルを開いて次の変数を設定してください:
$routes->setDefaultController('Blog');
'Blog' のところは使用したいコントローラのクラス名です。これで 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);
}
show_404();
}
プライベートメソッド¶
いくつかのケースでは、特定のメソッドを公開アクセスから隠したいことがあるでしょう。 そのためには、単にメソッドを private または protected として定義してください。URI リクエスト経由では呼び出されなくなります。例として、次のようなメソッドがあるならば:
protected function utility()
{
// いくらかのコード
}
URL 経由でアクセスしようとしても、これは動きません:
example.com/index.php/blog/utility/
コントローラをサブディレクトリに整理する¶
もし大型アプリケーションを作っているなら、コントローラをサブディレクトリに入れて、階層的な整理ないし構造化したいことでしょう。CodeIgniter はそうすることができます。
単純にサブディレクトリを application/Controllers/ の下に作り、コントローラクラスをその中においてください。
注釈
この機能を使ったら、URI の第1セグメントにはフォルダ名を指定しなければなりません。例えば、こんなコントローラを持っているとしましょう:
application/controllers/products/Shoes.php
上のコントローラを呼ぶには、URI は次のようなものになります:
example.com/index.php/products/shoes/show/123
それぞれのサブディレクトリにはデフォルトコントローラを持たせられます。URI にサブディレクトリ だけ が指定されているときに呼ばれます。シンプルに、application/Config/Routes.php で指定したデフォルトコントローラ名に一致するコントローラを配置してください。
また、CodeIgniter では URI ルーティング 機能を使用することで URI の再マッピングが可能です。
クラスのコンストラクタ¶
もしコントローラのコンストラクタを使いたいなら、次のコードをコンストラクタに 必ず 書かなければなりません:
parent::__construct(...$params);
この記述の必要性の理由は、そのローカルのコンストラクタは親コントローラクラスのコンストラクタをオーバーライドするためで、そのため手動で呼び出してやる必要があります。
例:
<?php
class Blog extends \CodeIgniter\Controller
{
public function __construct(...$params)
{
parent::__construct(...$params);
// 独自のコンストラクタのコード
}
}
デフォルト値を設定したい場合にコンストラクタは有用です。クラスがインスタンス化するときにデフォルトで処理が走ります。コンストラクタは値を return できませんが、いくらかのデフォルト処理をするものです。
持っているプロパティ¶
すべてのコントローラは CodeIgniter\Controller
クラスを継承する必要があります。
このクラスはすべてのコントローラで有効になるいくつかの機能を提供します。
リクエストオブジェクト¶
アプリケーションのメインの リクエストインスタンス はクラスのプロパティ $this->request
として常に利用可能です。
レスポンスオブジェクト¶
アプリケーションのメインの レスポンスインスタンス はクラスのプロパティ $this->response
として常に利用可能です。
HTTPS 強制¶
メソッドにHTTPS 経由のアクセスを強制するための便利なメソッドが、すべてのコントローラ内で利用可能です:
if (!$this->request->isSecure())
{
$this->forceHTTPS();
}
デフォルトでは、モダンなブラウザでは HTTP Strict Transport Security ヘッダをサポートしていますが、この呼び出しはブラウザに non-HTTPS 呼び出しから HTTPS 呼び出しへ強制するのを1年間としています。第1引数でその期間(秒単位)を変更できます:
if (!$this->request->isSecure())
{
$this->forceHTTPS(31536000); // 1年
}
注釈
多くの 時間ベースの定数 が常に利用可能です。年、月、そのほかも。
$_POST データのバリデーション¶
また、コントローラは $_POST データのバリデーションをすこしだけシンプルにする便利メソッドを提供しています。validate()
の第1引数は現在の Request、第2引数にはバリデーションルールの配列、そしてオプションとして、通過できなかった場合のカスタムエラーメッセージの配列です。バリデーションライブラリドキュメント
にはルールとメッセージの配列の形式と利用可能なルールについて、詳細が書かれています:
public function updateUser(int $userID)
{
if (!$this->validate($this->request, [
'email' => "required|is_unique[users.email,id,{$userID}]",
'name' => 'required|alpha_numeric_spaces'
]))
{
return view('users/update', [
'errors' => $this->errors
]);
}
// 成功したときに行うことをここに
}
もしルールを設定ファイルに保存しておくのがより簡便と考えるなら、$rules 配列をグループ名に置き換え、Config\Validation.php
に定義することができます:
public function updateUser(int $userID)
{
if (!$this->validate($this->request, 'userRules'))
{
return view('users/update', [
'errors' => $this->errors
]);
}
// 成功したときに行うことをここに
}
注釈
また、バリデーションはモデルで自動処理させることもできます。どこでバリデーションをするかはあなた次第です。いくつかの状況ではモデルよりコントローラのほうがシンプルに思われるでしょうし、逆もまた然りです。
これでおしまいです!¶
これが、かいつまんでですが、コントローラについて知るべきことのすべてです。