検証

CodeIgniterは、記述するコード量を最小限に抑えるのに役立つ包括的なデータ検証クラスを提供します。

概要

CodeIgniterのデータ検証アプローチを説明する前に、理想的なシナリオを説明しましょう。

  1. フォームが表示されます。

  2. フォームに入力して送信します。

  3. 無効なものを送信した場合、または必須項目を忘れた場合、フォームは問題点を説明するエラーメッセージとともにデータを含めて再表示されます。

  4. このプロセスは、有効なフォームを送信するまで続きます。

受信側では、スクリプトは次のことを行う必要があります。

  1. 必須データの確認。

  2. データが正しいタイプであり、正しい基準を満たしていることを検証します。たとえば、ユーザー名が送信された場合、許可された文字のみが含まれるように検証する必要があります。最小の長さで、最大長を超えてはなりません。ユーザー名は他の既存のユーザー名にすることはできず、予約語にすることもできません。など。

  3. セキュリティのためにデータをサニタイズします。

  4. 必要に応じてデータを事前フォーマットします。

  5. データベースに挿入するデータを準備します。

上記プロセスについて特に複雑なことはありませんが、通常はかなりの量のコードが必要となり、エラーメッセージを表示するには、通常、さまざまな制御構造がフォームHTML内に配置されます。フォーム検証は、作成は簡単ですが、実装は一般的に非常に面倒で退屈です。

フォーム検証チュートリアル

以下は、CodeIgniterのフォーム検証を実装するための「ハンズオン」チュートリアルです。

フォーム検証を実装するには、次の3つのものが必要です。

  1. フォームを含むビューファイル。

  2. 送信が成功したときに表示される「成功」メッセージを含むビューファイル。

  3. 送信されたデータを受信して処理するコントローラーメソッド。

例としてメンバーのサインアップフォームを使用して、これら3つを作成しましょう。

フォーム

テキストエディターを使用して、signup.phpというフォームを作成します。その中にこのコードを記述し、app/Views/フォルダーに保存します

<html>
<head>
    <title>My Form</title>
</head>
<body>

    <?= validation_list_errors() ?>

    <?= form_open('form') ?>

        <h5>Username</h5>
        <input type="text" name="username" value="<?= set_value('username') ?>" size="50">

        <h5>Password</h5>
        <input type="text" name="password" value="<?= set_value('password') ?>" size="50">

        <h5>Password Confirm</h5>
        <input type="text" name="passconf" value="<?= set_value('passconf') ?>" size="50">

        <h5>Email Address</h5>
        <input type="text" name="email" value="<?= set_value('email') ?>" size="50">

        <div><input type="submit" value="Submit"></div>

    <?= form_close() ?>

</body>
</html>

成功ページ

テキストエディターを使用して、success.phpというフォームを作成します。その中にこのコードを記述し、app/Views/フォルダーに保存します

<html>
<head>
    <title>My Form</title>
</head>
<body>

    <h3>Your form was successfully submitted!</h3>

    <p><?= anchor('form', 'Try it again!') ?></p>

</body>
</html>

コントローラー

テキストエディターを使用して、Form.phpというコントローラーを作成します。その中にこのコードを記述し、app/Controllers/フォルダーに保存します

<?php

namespace App\Controllers;

class Form extends BaseController
{
    protected $helpers = ['form'];

    public function index()
    {
        if (! $this->request->is('post')) {
            return view('signup');
        }

        $rules = [
            // @TODO
        ];

        $data = $this->request->getPost(array_keys($rules));

        if (! $this->validateData($data, $rules)) {
            return view('signup');
        }

        // If you want to get the validated data.
        $validData = $this->validator->getValidated();

        return view('success');
    }
}

注意

$this->request->is()メソッドはv4.3.0から使用できます。以前のバージョンでは、if (strtolower($this->request->getMethod()) !== 'post')を使用する必要があります。

注意

$this->validator->getValidated()メソッドはv4.4.0から使用できます。

ルート

次に、app/Config/Routes.phpでコントローラーのルートを追加します

// ...

$routes->get('form', 'Form::index');
$routes->post('form', 'Form::index');

// ...

試してみよう!

フォームを試すには、次のようなURLを使用してサイトにアクセスしてください

example.com/index.php/form/

フォームを送信すると、フォームが再読み込みされるだけが表示されます。これは、$this->validateData()で検証ルールを設定していないためです。

validateData()メソッドは、コントローラーのメソッドです。内部でValidationクラスを使用します。$this->validateData()を参照してください。

注意

validateData()メソッドにまだ何も検証するように指示していないため、デフォルトでfalse(ブール値のfalse)を返します。validateData()メソッドは、いずれも失敗せずにルールが正常に適用された場合にのみtrueを返します。

説明

上記のページについて、いくつかの点に気づくでしょう。

signup.php

フォーム(signup.php)は、いくつかの例外を除いて、標準のWebフォームです

  1. フォームヘルパーを使用して、フォームの開始と終了を作成します。技術的には、これは必須ではありません。標準のHTMLを使用してフォームを作成できます。ただし、ヘルパーを使用する利点は、設定ファイルのURLに基づいてアクションURLを生成してくれることです。これにより、URLが変更された場合にアプリケーションの移植性が向上します。

  2. フォームの先頭に、次の関数呼び出しが表示されます

    <?= validation_list_errors() ?>
    

    この関数は、バリデーターから返されたエラーメッセージを返します。メッセージがない場合は、空の文字列を返します。

Form.php

コントローラー(Form.php)には、$helpersという1つのプロパティがあります。ビューファイルで使用されるフォームヘルパーをロードします。

コントローラーには、index()という1つのメソッドがあります。このメソッドは、非POSTリクエストが来たときにフォームを表示するためにsignupビューを返します。それ以外の場合は、コントローラーが提供する$this->validateData()メソッドを使用します。また、検証ルーチンも実行します。検証が成功したかどうかに基づいて、フォームまたは成功ページを表示します。

検証ルールの追加

次に、コントローラー(Form.php)に検証ルールを追加します

// ...

$rules = [
    'username' => 'required|max_length[30]',
    'password' => 'required|max_length[255]|min_length[10]',
    'passconf' => 'required|max_length[255]|matches[password]',
    'email'    => 'required|max_length[254]|valid_email',
];

// ...

フォームを送信すると、成功ページまたはエラーメッセージ付きのフォームが表示されます。

検証の設定

従来のルールと厳格なルール

CodeIgniter 4には、2種類の検証ルールクラスがあります。従来のルールクラス(従来のルール)の名前空間はCodeIgniter\Validationで、新しいクラス(厳格なルール)にはCodeIgniter\Validation\StrictRulesがあり、厳格な検証を提供します。

注意

v4.3.0以降、セキュリティ向上のため、厳格なルールがデフォルトで使用されるようになりました。

従来のルール

重要

従来のルールは、後方互換性のためだけに存在します。新しいプロジェクトでは使用しないでください。すでに使用している場合でも、厳格なルールに切り替えることをお勧めします。

警告

JSONデータなど、文字列以外の値を含むデータを検証する場合は、厳格なルールを使用することをお勧めします。

従来のルールは、文字列の値が検証されることを暗黙的に想定しており、入力値は暗黙的に文字列値に変換される場合があります。これは、POSTデータを検証するようなほとんどの基本的なケースで機能します。

ただし、例えばJSON入力データを使用する場合、それはbool/null/配列の型である可能性があります。ブール値trueを検証すると、従来のルールクラスでは文字列'1'に変換されます。integerルールで検証すると、'1'は検証をパスします。

厳格なルール

バージョン4.2.0で新しく追加されました。

厳格なルールは、暗黙的な型変換を使用しません。

従来のルールの使用

従来のルールを使用する場合は、app/Config/Validation.phpでルールクラスを変更する必要があります。

<?php

namespace Config;

// ...

class Validation extends BaseConfig
{
    // ...

    public array $ruleSets = [
        \CodeIgniter\Validation\CreditCardRules::class,
        \CodeIgniter\Validation\FileRules::class,
        \CodeIgniter\Validation\FormatRules::class,
        \CodeIgniter\Validation\Rules::class,
    ];

    // ...
}

ライブラリの読み込み

ライブラリは、validationという名前のサービスとしてロードされます。

$validation = \Config\Services::validation();

これにより、複数のルールセットと、簡単に再利用できるルールのコレクションを含む設定が含まれるConfig\Validationファイルが自動的にロードされます。

注意

コントローラーモデルの両方が検証をさらに簡単にするためのメソッドを提供しているため、このメソッドを使用する必要がない場合があります。

検証ルールの設定

CodeIgniterでは、指定されたフィールドに対して必要な数の検証ルールを設定し、それらを順番にカスケードすることができます。検証ルールを設定するには、setRule()setRules()、またはwithRequest()メソッドを使用します。

単一ルールの設定

setRule()

このメソッドは、単一のルールを設定します。メソッドのシグネチャは次のとおりです。

setRule(string $field, ?string $label, array|string $rules[, array $errors = []])

$rulesは、パイプ区切りのルールのリストまたはルールの配列コレクションのいずれかを受け入れます。

$validation->setRule('username', 'Username', 'required|max_length[30]|min_length[3]');
$validation->setRule('password', 'Password', ['required', 'max_length[255]', 'min_length[8]', 'alpha_numeric_punct']);

$fieldに渡す値は、送信されるデータ配列のキーと一致する必要があります。データが$_POSTから直接取得される場合は、フォームの入力名と正確に一致する必要があります。

警告

v4.2.0より前では、このメソッドの3番目のパラメータである$rulesは、stringを受け入れるように型ヒントされていました。v4.2.0以降では、配列も許可するように型ヒントが削除されました。このメソッドをオーバーライドする拡張クラスでLSPが壊れるのを避けるために、子クラスのメソッドも型ヒントを削除するように変更する必要があります。

複数のルールの設定

setRules()

setRule()と同様ですが、フィールド名とそのルールの配列を受け入れます。

$validation->setRules([
    'username' => 'required|max_length[30]',
    'password' => 'required|max_length[255]|min_length[10]',
]);
// or
$validation->setRules([
    'username' => ['required', 'max_length[30]'],
    'password' => ['required', 'max_length[255]', 'min_length[10]'],
]);

ラベル付きのエラーメッセージを表示するには、次のように設定できます。

$validation->setRules([
    'username' => ['label' => 'Username', 'rules' => 'required|max_length[30]'],
    'password' => ['label' => 'Password', 'rules' => 'required|max_length[255]|min_length[10]'],
]);
// or
$validation->setRules([
    'username' => ['label' => 'Username', 'rules' => 'required|max_length[30]'],
    'password' => ['label' => 'Password', 'rules' => ['required', 'max_length[255]', 'min_length[10]']],
]);

注意

setRules()は、以前に設定されたルールをすべて上書きします。既存のルールセットに複数のルールを追加するには、setRule()を複数回使用します。

配列データのルール設定

データがネストされた連想配列にある場合は、「ドット配列構文」を使用してデータを簡単に検証できます。

/*
 * The data to test:
 * [
 *     'contacts' => [
 *         'name' => 'Joe Smith',
 *         'friends' => [
 *             [
 *                 'name' => 'Fred Flinstone',
 *             ],
 *             [
 *                 'name' => 'Wilma',
 *             ],
 *         ]
 *     ]
 * ]
 */

// Joe Smith
$validation->setRules([
    'contacts.name' => 'required|max_length[60]',
]);

*ワイルドカード記号を使用して、配列の任意の1つのレベルに一致させることができます。

// Fred Flintsone & Wilma
$validation->setRules([
    'contacts.friends.*.name' => 'required|max_length[60]',
]);

注意

v4.4.4より前では、バグにより、ワイルドカード*が誤った次元でデータを検証していました。詳細については、アップグレードを参照してください。

「ドット配列構文」は、1次元の配列データがある場合にも役立ちます。例えば、複数選択ドロップダウンによって返されるデータなど。

/*
 * The data to test:
 * [
 *     'user_ids' => [
 *         1,
 *         2,
 *         3,
 *     ]
 * ]
 */

// Rule
$validation->setRules([
    'user_ids.*' => 'required|max_length[19]',
]);

withRequest()

重要

このメソッドは、後方互換性のためだけに存在します。新しいプロジェクトでは使用しないでください。すでに使用している場合でも、別のより適切なメソッドを使用することをお勧めします。

警告

POSTデータのみを検証する場合は、withRequest()を使用しないでください。このメソッドは、$request->getVar()を使用し、これは$_GET$_POST、または$_COOKIEデータをその順序で返します(php.iniのrequest-orderに依存)。新しい値は古い値を上書きします。POST値は、同じ名前のクッキーによって上書きされる可能性があります。

検証ライブラリを使用する最も一般的なケースの1つは、HTTPリクエストから入力されたデータを検証する場合です。必要に応じて、現在のRequestオブジェクトのインスタンスを渡すと、すべての入力データが取得され、検証対象のデータとして設定されます。

$validation = \Config\Services::validation();
$request    = \Config\Services::request();

if ($validation->withRequest($request)->run()) {
    // If you use the input data, you should get it from the getValidated() method.
    // Otherwise you may create a vulnerability.
    $validData = $validation->getValidated();

    // ...
}

警告

このメソッドを使用する場合は、検証済みのデータを取得するためにgetValidated()メソッドを使用する必要があります。このメソッドは、リクエストがJSONリクエスト(Content-Type: application/json)の場合、$request->getJSON()からJSONデータを取得するか、リクエストがPUT、PATCH、DELETEリクエストでHTMLフォームポスト(Content-Type: multipart/form-data)ではない場合、$request->getRawInput()から生のデータを取得するか、$request->getVar()からデータを取得するため、攻撃者が検証されるデータを変更する可能性があります。

注意

getValidated()メソッドはv4.4.0以降で使用できます。

検証の操作

検証の実行

run()メソッドは検証を実行します。メソッドのシグネチャは次のとおりです。

run(?array $data = null, ?string $group = null, ?string $dbGroup = null): bool

$dataは、検証するデータの配列です。オプションの2番目のパラメータである$groupは、適用する事前定義されたルールのグループです。オプションの3番目のパラメータである$dbGroupは、使用するデータベースグループです。

このメソッドは、検証が成功した場合はtrueを返します。

if (! $validation->run($data)) {
    // handle validation errors
}
// or
if (! $validation->run($data, 'signup')) {
    // handle validation errors
}

複数の検証の実行

注意

run()メソッドはエラー状態をリセットしません。以前の実行が失敗した場合、run()は常にfalseを返し、getErrors()は明示的にリセットされるまで以前のすべてのエラーを返します。

例えば、異なるデータセットや、1つの実行後​​に異なるルールで複数の検証を実行する場合は、各実行前に$validation->reset()を呼び出して、前の実行のエラーを取り除く必要がある場合があります。reset()は、以前に設定したデータ、ルール、またはカスタムエラーを無効にするため、setRules()setRuleGroup()などを繰り返す必要があることに注意してください。

foreach ($userAccounts as $user) {
    $validation->reset();
    $validation->setRules($userAccountRules);

    if (! $validation->run($user)) {
        // handle validation errors
    }
}

1つの値の検証

check()メソッドは、ルールに対して1つの値を検証します。最初のパラメータ$valueは、検証する値です。2番目のパラメータ$ruleは、検証ルールです。オプションの3番目のパラメータ$errorsは、カスタムエラーメッセージです。

if ($validation->check($value, 'required')) {
    // $value is valid.
}

注意

v4.4.0より前では、このメソッドの2番目のパラメータである$ruleは、stringを受け入れるように型ヒントされていました。v4.4.0以降では、配列も許可するように型ヒントが削除されました。

注意

このメソッドは、内部でルールを設定するためにsetRule()メソッドを呼び出します。

検証済みデータの取得

バージョン4.4.0で新しく追加されました。

実際の検証済みデータは、getValidated()メソッドで取得できます。このメソッドは、検証ルールによって検証された要素のみの配列を返します。

$validation = \Config\Services::validation();
$validation->setRules([
    'username' => 'required',
    'password' => 'required|min_length[10]',
]);

$data = [
    'username'   => 'john',
    'password'   => 'BPi-$Swu7U5lm$dX',
    'csrf_token' => '8b9218a55906f9dcc1dc263dce7f005a',
];

if ($validation->run($data)) {
    $validatedData = $validation->getValidated();
    // $validatedData = [
    //     'username' => 'john',
    //     'password' => 'BPi-$Swu7U5lm$dX',
    // ];
}
// In Controller.

if (! $this->validate([
    'username' => 'required',
    'password' => 'required|min_length[10]',
])) {
    // The validation failed.
    return view('login', [
        'errors' => $this->validator->getErrors(),
    ]);
}

// The validation was successful.

// Get the validated data.
$validData = $this->validator->getValidated();

検証ルールのセットを構成ファイルに保存する

Validationクラスの優れた機能として、アプリケーション全体のすべての検証ルールを構成ファイルに保存できる点が挙げられます。ルールは「グループ」に整理します。検証を実行するたびに異なるグループを指定できます。

ルールの保存方法

検証ルールを保存するには、Config\Validationクラスに、グループの名前を持つ新しいpublicプロパティを作成します。この要素は、検証ルールを含む配列を保持します。前述のように、検証配列は以下のプロトタイプを持ちます。

<?php

namespace Config;

// ...

class Validation extends BaseConfig
{
    // ...

    public array $signup = [
        'username'     => 'required|max_length[30]',
        'password'     => 'required|max_length[255]',
        'pass_confirm' => 'required|max_length[255]|matches[password]',
        'email'        => 'required|max_length[254]|valid_email',
    ];

    // ...
}

ルールグループの指定方法

run()メソッドを呼び出す際に使用するグループを指定できます。

$validation->run($data, 'signup');

エラーメッセージの保存方法

この構成ファイルには、グループと同じ名前で、末尾に_errorsを付加したプロパティを作成することで、カスタムエラーメッセージを保存することもできます。これらのエラーメッセージは、このグループが使用される際、自動的にすべてのエラーに使用されます。

<?php

namespace Config;

// ...

class Validation extends BaseConfig
{
    // ...

    public array $signup = [
        'username'     => 'required|max_length[30]',
        'password'     => 'required|max_length[255]',
        'pass_confirm' => 'required|max_length[255]|matches[password]',
        'email'        => 'required|max_length[254]|valid_email',
    ];

    public array $signup_errors = [
        'username' => [
            'required' => 'You must choose a username.',
        ],
        'email' => [
            'valid_email' => 'Please check the Email field. It does not appear to be valid.',
        ],
    ];

    // ...
}

または、すべての設定を配列で渡すこともできます。

<?php

namespace Config;

// ...

class Validation extends BaseConfig
{
    // ...

    public array $signup = [
        'username' => [
            'rules'  => 'required|max_length[30]',
            'errors' => [
                'required' => 'You must choose a Username.',
            ],
        ],
        'email' => [
            'rules'  => 'required|max_length[254]|valid_email',
            'errors' => [
                'valid_email' => 'Please check the Email field. It does not appear to be valid.',
            ],
        ],
    ];

    // ...
}

配列の書式設定の詳細については、カスタムエラーメッセージの設定を参照してください。

ルールグループの取得と設定

ルールグループの取得

このメソッドは、検証構成からルールグループを取得します。

$validation->getRuleGroup('signup');
ルールグループの設定

このメソッドは、検証構成から検証サービスにルールグループを設定します。

$validation->setRuleGroup('signup');

検証プレースホルダー

Validationクラスには、渡されたデータに基づいてルールの一部を置き換えるための簡単なメソッドが用意されています。これは少々分かりにくいかもしれませんが、is_unique検証ルールを使用する際に特に便利です。プレースホルダーは、$dataとして渡されたフィールド(または配列キー)の名前を中括弧で囲んだものです。これは、一致する入力フィールドのに置き換えられます。例を挙げると分かりやすくなります。

$validation->setRules([
    'id'    => 'max_length[19]|is_natural_no_zero',
    'email' => 'required|max_length[254]|valid_email|is_unique[users.email,id,{id}]',
]);

注意

v4.3.5以降、セキュリティのためにプレースホルダーフィールド(上記のサンプルコードのidフィールド)の検証ルールを設定する必要があります。

このルールセットでは、メールアドレスはデータベース内で一意であるべきですが、プレースホルダーの値に一致するIDを持つ行は除外されます。フォームのPOSTデータが以下であったと仮定します。

$_POST = [
    'id'    => 4,
    'email' => '[email protected]',
];

すると、{id}プレースホルダーは数値の4に置き換えられ、以下の修正されたルールになります。

$validation->setRules([
    'id'    => 'max_length[19]|is_natural_no_zero',
    'email' => 'required|max_length[254]|valid_email|is_unique[users.email,id,4]',
]);

したがって、メールアドレスが一意であることを検証する際、id=4を持つデータベース内の行は無視されます。

注意

v4.3.5以降、プレースホルダー(id)の値が検証に合格しない場合、プレースホルダーは置き換えられません。

これは、実行時にさらに動的なルールを作成するためにも使用できます。ただし、渡される動的なキーがフォームデータと競合しないように注意する必要があります。

エラーの処理

Validationライブラリには、エラーメッセージの設定、カスタムエラーメッセージの提供、表示する1つまたは複数のエラーの取得を支援するいくつかのメソッドが用意されています。

デフォルトでは、エラーメッセージはsystem/Language/en/Validation.phpにある言語文字列から派生します。各ルールにはエントリがあります。メッセージのデフォルトを変更する場合は、app/Language/en/Validation.php(および/またはenの代わりに/加えて使用するロケールの対応するフォルダ)というファイルを作成し、異なるデフォルトを設定したいエラーメッセージのキーと値を配置します。

カスタムエラーメッセージの設定

setRule()メソッドとsetRules()メソッドの両方で、各フィールドに固有のエラーとして使用されるカスタムメッセージの配列を最後のパラメーターとして受け入れることができます。これにより、エラーが各インスタンスに合わせて調整されるため、ユーザーにとって非常に快適なエクスペリエンスが提供されます。カスタムエラーメッセージが提供されていない場合は、デフォルト値が使用されます。

カスタムエラーメッセージを提供するには、次の2つの方法があります。

最後のパラメーターとして

$validation->setRules(
    [
        'username' => 'required|max_length[30]|is_unique[users.username]',
        'password' => 'required|max_length[254]|min_length[10]',
    ],
    [   // Errors
        'username' => [
            'required' => 'All accounts must have usernames provided',
        ],
        'password' => [
            'min_length' => 'Your password is too short. You want to get hacked?',
        ],
    ]
);

または、ラベル付きスタイルとして

$validation->setRules([
    'username' => [
        'label'  => 'Username',
        'rules'  => 'required|max_length[30]|is_unique[users.username]',
        'errors' => [
            'required' => 'All accounts must have {field} provided',
        ],
    ],
    'password' => [
        'label'  => 'Password',
        'rules'  => 'required|max_length[255]|min_length[10]',
        'errors' => [
            'min_length' => 'Your {field} is too short. You want to get hacked?',
        ],
    ],
]);

フィールドの「人間が読める」名前、または一部のルールで許可されているオプションのパラメーター(max_lengthなど)、または検証された値を含める場合は、メッセージに{field}{param}{value}タグをそれぞれ追加できます。

'min_length' => 'Supplied value ({value}) for {field} must have at least {param} characters.'

「ユーザー名」という人間が読める名前のフィールドと、「Pizza」という値を持つmin_length[6]のルールを使用すると、「ユーザー名の指定された値(Pizza)は、少なくとも6文字である必要があります。」というエラーが表示されます。

警告

getErrors()またはgetError()を使用してエラーメッセージを取得する場合、メッセージはHTMLエスケープされません。エラーメッセージを作成するために({value})のようなユーザー入力データを使用すると、HTMLタグが含まれている可能性があります。表示する前にメッセージをエスケープしないと、XSS攻撃が可能になります。

注意

ラベル付きスタイルのエラーメッセージを使用する場合、setRules()に2番目のパラメーターを渡すと、最初のパラメーターの値で上書きされます。

メッセージと検証ラベルの翻訳

言語ファイルから翻訳された文字列を使用するには、ドット構文を使用するだけです。ここに翻訳を含むファイルがあると考えてみましょう。**app/Languages/en/Rules.php**。このファイルで定義されている言語行を、このように使用できます。

$validation->setRules([
    'username' => [
        'label'  => 'Rules.username',
        'rules'  => 'required|max_length[30]|is_unique[users.username]',
        'errors' => [
            'required' => 'Rules.username.required',
        ],
    ],
    'password' => [
        'label'  => 'Rules.password',
        'rules'  => 'required|max_length[255]|min_length[10]',
        'errors' => [
            'min_length' => 'Rules.password.min_length',
        ],
    ],
]);

すべてのエラーの取得

失敗したフィールドのすべてのエラーメッセージを取得する必要がある場合は、getErrors()メソッドを使用できます。

$errors = $validation->getErrors();
/*
 * Produces:
 * [
 *     'field1' => 'error message',
 *     'field2' => 'error message',
 * ]
 */

エラーが存在しない場合は、空の配列が返されます。

ワイルドカード(*)を使用すると、エラーは特定フィールドを指し、アスタリスクは適切なキー/キーに置き換えられます。

// for data
'contacts' => [
    'friends' => [
        [
            'name' => 'Fred Flinstone',
        ],
        [
            'name' => '',
        ],
    ]
]

// rule
'contacts.friends.*.name' => 'required'

// error will be
'contacts.friends.1.name' => 'The contacts.friends.*.name field is required.'

単一エラーの取得

getError()メソッドを使用して、単一フィールドのエラーを取得できます。唯一のパラメーターはフィールド名です。

$error = $validation->getError('username');

エラーが存在しない場合は、空の文字列が返されます。

注意

ワイルドカードを使用すると、マスクに一致するすべてのエラーが見つかり、EOL文字で区切られた1行に結合されます。

エラーの存在確認

hasError()メソッドを使用して、エラーが存在するかどうかを確認できます。唯一のパラメーターはフィールド名です。

if ($validation->hasError('username')) {
    echo $validation->getError('username');
}

ワイルドカードを使用してフィールドを指定すると、マスクに一致するすべてのエラーがチェックされます。

/*
 * For errors:
 * [
 *     'foo.0.bar'   => 'Error',
 *     'foo.baz.bar' => 'Error',
 * ]
 */

// returns true
$validation->hasError('foo.*.bar');

リダイレクトと検証エラー

PHPはリクエスト間で何も共有しません。したがって、検証が失敗した場合にリダイレクトすると、前のリクエストで検証が実行されたため、リダイレクトされたリクエストに検証エラーは表示されません。

その場合は、フォームヘルパー関数validation_errors()validation_list_errors()、およびvalidation_show_error()を使用する必要があります。これらの関数は、セッションに保存されている検証エラーを確認します。

検証エラーをセッションに保存するには、redirect()withInput()を使用する必要があります。

// In Controller.
if (! $this->validateData($data, $rules)) {
    return redirect()->back()->withInput();
}

エラー表示のカスタマイズ

$validation->listErrors()または$validation->showError()を呼び出すと、バックグラウンドでエラーの表示方法を決定するビューファイルがロードされます。デフォルトでは、ラッピングdivにerrorsクラスが表示されます。新しいビューを簡単に作成し、アプリケーション全体で使用できます。

ビューの作成

最初の手順は、カスタムビューを作成することです。これらは、view()メソッドがそれらを検出できる場所ならどこにでも配置できます。つまり、標準のViewディレクトリ、または名前空間付きのViewフォルダーが機能します。たとえば、**app/Views/_errors_list.php**に新しいビューを作成できます。

<?php if (! empty($errors)): ?>
    <div class="alert alert-danger" role="alert">
        <ul>
        <?php foreach ($errors as $error): ?>
            <li><?= esc($error) ?></li>
        <?php endforeach ?>
        </ul>
    </div>
<?php endif ?>

ビュー内では、エラーのリストを含む $errors という名前の配列が利用可能です。この配列では、キーがエラーが発生したフィールドの名前で、値がエラーメッセージです。例えば、以下のようになります。

$errors = [
    'username' => 'The username field must be unique.',
    'email'    => 'You must provide a valid email address.',
];

実際には、作成できるビューには2つのタイプがあります。1つ目は、すべてのエラーの配列を含むもので、先ほど見たものです。もう1つのタイプはよりシンプルで、エラーメッセージを含む単一の変数 $error のみを含みます。これは、フィールドを指定する必要がある showError() メソッドで使用されます。

<span class="help-block"><?= esc($error) ?></span>

設定

ビューを作成したら、Validationライブラリにそれらを知らせる必要があります。app/Config/Validation.php を開いてください。中には、好きなだけカスタムビューをリストできる $templates プロパティがあり、それらを参照できる短いエイリアスを提供できます。上記の例のファイルを追加する場合、次のようになります。

<?php

namespace Config;

// ...

class Validation extends BaseConfig
{
    // ...

    public array $templates = [
        'list'    => 'CodeIgniter\Validation\Views\list',
        'single'  => 'CodeIgniter\Validation\Views\single',
        'my_list' => '_errors_list',
    ];

    // ...
}

テンプレートの指定

listErrors() の最初のパラメータとしてエイリアスを渡すことで、使用するテンプレートを指定できます。

<?= $validation->listErrors('my_list') ?>

フィールド固有のエラーを表示する場合は、showError() メソッドの2番目のパラメータとして、エラーが属するフィールドの名前の直後にエイリアスを渡すことができます。

<?= $validation->showError('username', 'my_single') ?>

カスタムルールの作成

ルールクラスの使用

ルールは、名前空間を持つシンプルなクラス内に保存されます。オートローダーがそれを見つけられる限り、好きな場所に保存できます。これらのファイルはRuleSetsと呼ばれます。

RuleSetの追加

新しいRuleSetを追加するには、app/Config/Validation.php を編集し、$ruleSets 配列に新しいファイルを追加します。

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;
use CodeIgniter\Validation\CreditCardRules;
use CodeIgniter\Validation\FileRules;
use CodeIgniter\Validation\FormatRules;
use CodeIgniter\Validation\Rules;

class Validation extends BaseConfig
{
    // ...

    public array $ruleSets = [
        Rules::class,
        FormatRules::class,
        FileRules::class,
        CreditCardRules::class,
    ];

    // ...
}

完全修飾クラス名を持つ単純な文字列として、または上記のように ::class サフィックスを使用して追加できます。ここでの主な利点は、より高度なIDEで追加のナビゲーション機能を提供することです。

ルールクラスの作成

ファイル自体では、各メソッドはルールであり、最初のパラメータとして検証する値を受け入れ、テストに合格した場合はブール値のtrueを、合格しなかった場合はfalseを返す必要があります。

<?php

class MyRules
{
    public function even($value): bool
    {
        return (int) $value % 2 === 0;
    }
}

デフォルトでは、システムはエラー内で使用される言語文字列を system/Language/en/Validation.php 内で検索します。カスタムルールのデフォルトエラーメッセージを提供するには、app/Language/en/Validation.php (および、en の代わりにロケールで使用する対応するフォルダー)にそれらを配置できます。また、デフォルトの Validation.php の代わりに他の言語文字列ファイルを使用したい場合は、2番目のパラメータ(または、ルールがパラメータで動作する必要がある場合は、以下で説明するように4番目のパラメータ)で、参照によって &$error 変数を受け入れることで、エラーメッセージを提供できます。

<?php

class MyRules
{
    public function even($value, ?string &$error = null): bool
    {
        if ((int) $value % 2 !== 0) {
            $error = lang('myerrors.evenError');

            return false;
        }

        return true;
    }
}

カスタムルールの使用

新しいカスタムルールは、他のルールとまったく同じように使用できるようになりました。

$validation->setRules([
    'foo' => 'required|max_length[19]|even',
]);

パラメータの許可

メソッドがパラメータで動作する必要がある場合、関数には最低3つのパラメータが必要です。

  1. 検証する値($value)

  2. パラメータ文字列($params)

  3. フォームで送信されたすべてのデータを含む配列($data)

  4. (オプション)カスタムエラー文字列(&$error)、上記の説明のとおり。

警告

$data のフィールド値は、検証されていない(または無効な場合がある)ものです。検証されていない入力データを使用することは、脆弱性の原因となります。カスタムルール内で、$data のデータを使用する前に必要な検証を実行する必要があります。

$data 配列は、結果を基にするために、送信された別のフィールドの値を確認する必要がある required_with のようなルールに特に便利です。

<?php

class MyRules
{
    public function required_with($value, string $params, array $data): bool
    {
        $params = explode(',', $params);

        // If the field is present we can safely assume that
        // the field is here, no matter whether the corresponding
        // search field is present or not.
        $present = $this->required($value ?? '');

        if ($present) {
            return true;
        }

        // Still here? Then we fail this test if
        // any of the fields are present in $data
        // as $fields is the lis
        $requiredFields = [];

        foreach ($params as $field) {
            if (array_key_exists($field, $data)) {
                $requiredFields[] = $field;
            }
        }

        // Remove any keys with empty values since, that means they
        // weren't truly there, as far as this is concerned.
        $requiredFields = array_filter($requiredFields, static fn ($item) => ! empty($data[$item]));

        return empty($requiredFields);
    }
}

クロージャルールの使用

バージョン4.3.0で新規追加。

アプリケーション全体でカスタムルールの機能を一度だけ使用する必要がある場合は、ルールクラスの代わりにクロージャを使用できます。

検証ルールには配列を使用する必要があります。

$validation->setRules(
    [
        'foo' => [
            'required',
            static fn ($value) => (int) $value % 2 === 0,
        ],
    ],
    [
        // Errors
        'foo' => [
            // Specify the array key for the closure rule.
            1 => 'The value is not even.',
        ],
    ],
);

if (! $validation->run($data)) {
    // handle validation errors
}

クロージャルールのエラーメッセージを設定する必要があります。エラーメッセージを指定するときは、クロージャルールの配列キーを設定します。上記のコードでは、required ルールのキーは 0 で、クロージャのキーは 1 です。

または、次のパラメータを使用できます。

$validation->setRules([
    'foo' => [
        'required',
        static function ($value, $data, &$error, $field) {
            if ((int) $value % 2 === 0) {
                return true;
            }

            $error = 'The value is not even.';

            return false;
        },
    ],
]);

利用可能なルール

注意

ルールは文字列です。特に is_unique ルールの場合、パラメータの間にスペースは含めない必要があります。ignore_value の前後にスペースを含めることはできません。

// is_unique[table.field,ignore_field,ignore_value]

$validation->setRules([
    'name' => "max_length[36]|is_unique[supplier.name,uuid, {$uuid}]", // is not ok
    'name' => "max_length[36]|is_unique[supplier.name,uuid,{$uuid} ]", // is not ok
    'name' => "max_length[36]|is_unique[supplier.name,uuid,{$uuid}]",  // is ok
    'name' => 'max_length[36]|is_unique[supplier.name,uuid,{uuid}]',   // is ok - see "Validation Placeholders"
]);
// Warning: If `$uuid` is a user input, be sure to validate the format of the value before using it.
// Otherwise, it is vulnerable.

一般利用向けのルール

以下は、使用可能なすべてのネイティブルールのリストです。

ルール

パラメータ

説明

alpha

なし

フィールドにASCIIのアルファベット文字以外のものが含まれている場合、失敗します。

alpha_space

なし

フィールドにASCIIのアルファベット文字またはスペース以外のものが含まれている場合、失敗します。

alpha_dash

なし

フィールドにASCIIの英数字、アンダースコア、またはダッシュ以外のものが含まれている場合、失敗します。

alpha_numeric

なし

フィールドにASCIIの英数字以外のものが含まれている場合、失敗します。

alpha_numeric_space

なし

フィールドにASCIIの英数字またはスペース以外のものが含まれている場合、失敗します。

alpha_numeric_punct

なし

フィールドに英数字、スペース、または以下の限定された句読点文字以外のものが含まれている場合、失敗します:~(チルダ)、!(感嘆符)、#(番号記号)、$(ドル記号)、%(パーセント記号)、&(アンパサンド)、*(アスタリスク)、-(ダッシュ)、_(アンダースコア)、+(プラス記号)、=(等号)、|(縦線)、:(コロン)、.(ピリオド)。

decimal

なし

フィールドに10進数以外のものが含まれている場合、失敗します。数値に + または - 符号も使用できます。

differs

はい

フィールドがパラメータ内のものと異なる場合、失敗します。

differs[field_name]

exact_length

はい

フィールドがパラメータ値とまったく異なる場合、失敗します。1つ以上のコンマ区切り値。

exact_length[5] または exact_length[5,8,12]

greater_than

はい

フィールドがパラメータ値以下の場合、または数値でない場合、失敗します。

greater_than[8]

greater_than_equal_to

はい

フィールドがパラメータ値より小さい場合、または数値でない場合、失敗します。

greater_than_equal_to[5]

hex

なし

フィールドに16進数文字以外のものが含まれている場合、失敗します。

if_exist

なし

このルールが存在する場合、検証は検証するデータにフィールドキーが存在する場合にのみフィールドをチェックします。

in_list

はい

フィールドがあらかじめ決められたリスト内にない場合、失敗します。

in_list[red,blue,green]

integer

なし

フィールドに整数以外のものが含まれている場合、失敗します。

is_natural

なし

フィールドに自然数(0、1、2、3など)以外のものが含まれている場合、失敗します。

is_natural_no_zero

なし

フィールドにゼロ以外の自然数(1、2、3など)以外のものが含まれている場合、失敗します。

is_not_unique

はい

指定された値が存在するかどうかをデータベースで確認します。(現在、1つのフィルターのみを受け入れます)フィルタリングするフィールド/値でレコードを無視できます。

is_not_unique[table.field,where_field,where_value]

is_unique

はい

このフィールド値がデータベースに存在するかどうかを確認します。必要に応じて、無視する列と値を設定します。これは、レコード自体を無視するために更新する場合に役立ちます。

is_unique[table.field,ignore_field,ignore_value]

less_than

はい

フィールドがパラメータ値以上の場合、または数値でない場合、失敗します。

less_than[8]

less_than_equal_to

はい

フィールドがパラメータ値より大きい場合、または数値でない場合、失敗します。

less_than_equal_to[8]

matches

はい

値は、パラメータ内のフィールドの値と一致する必要があります。

matches[field]

max_length

はい

フィールドがパラメータ値より長い場合、失敗します。

max_length[8]

min_length

はい

フィールドがパラメータ値より短い場合、失敗します。

min_length[3]

not_in_list

はい

フィールドがあらかじめ決められたリスト内にある場合、失敗します。

not_in_list[red,blue,green]

numeric

なし

フィールドに数値文字以外のものが含まれている場合、失敗します。

regex_match

はい

フィールドが正規表現に一致しない場合、失敗します。

regex_match[/regex/]

permit_empty

なし

フィールドが空の配列、空の文字列、null、またはfalseを受け入れることができるようにします。

required

なし

フィールドが空の配列、空の文字列、null、またはfalseの場合、失敗します。

required_with

はい

データ内の他のフィールドが empty() でない場合に、このフィールドが必要になります。

required_with[field1,field2]

required_without

はい

データ内の他のフィールドが empty() の場合に、このフィールドが必要になります。

required_without[field1,field2]

string

なし

要素が文字列であることを確認する、alpha *ルールの一般的な代替。

timezone

なし

フィールドが timezone_identifiers_list() に従ってタイムゾーンと一致しない場合、失敗します。

valid_base64

なし

フィールドに有効なBase64文字以外のものが含まれている場合、失敗します。

valid_json

なし

フィールドに有効なJSON文字列が含まれていない場合、失敗します。

valid_email

なし

フィールドに有効なメールアドレスが含まれていない場合、失敗します。

valid_emails

なし

コンマ区切りリストで提供された値に有効なメールが含まれていない場合、失敗します。

valid_ip

はい

指定されたIPが有効でない場合に失敗します。オプションのパラメータとして、IP形式を指定するために ipv4 または ipv6 を受け入れます。

valid_ip[ipv6]

valid_url

なし

フィールドに(緩い)URLが含まれていない場合に失敗します。「codeigniter」のようなホスト名となりうる単純な文字列も含まれます。通常は、valid_url_strict を使用する必要があります。

valid_url_strict

はい

フィールドに有効なURLが含まれていない場合に失敗します。オプションで有効なスキーマのリストを指定できます。指定しない場合、http,https が有効です。このルールはPHPの FILTER_VALIDATE_URL を使用します。

valid_url_strict[https]

valid_date

はい

フィールドに有効な日付が含まれていない場合に失敗します。日付形式に一致させるためのオプションのパラメータを指定しない場合、strtotime() が受け入れる任意の文字列が有効です。そのため、通常はパラメータを指定する必要があります。

valid_date[d/m/Y]

valid_cc_number

はい

クレジットカード番号が、指定されたプロバイダーが使用する形式に一致することを確認します。現在サポートされているプロバイダーは、American Express (amex)、China Unionpay (unionpay)、Diners Club CarteBlance (carteblanche)、Diners Club (dinersclub)、Discover Card (discover)、Interpayment (interpayment)、JCB (jcb)、Maestro (maestro)、Dankort (dankort)、NSPK MIR (mir)、Troy (troy)、MasterCard (mastercard)、Visa (visa)、UATP (uatp)、Verve (verve)、CIBC Convenience Card (cibc)、Royal Bank of Canada Client Card (rbc)、TD Canada Trust Access Card (tdtrust)、Scotiabank Scotia Card (scotia)、BMO ABM Card (bmoabm)、HSBC Canada Card (hsbc) です。

valid_cc_number[amex]

注意

また、少なくとも1つのパラメータ(検証するフィールドデータ)を受け取り、ブール値を返す任意のネイティブPHP関数を使用することもできます。検証ライブラリは、検証するデータを決して変更しません

ファイルアップロードのルール

アップロードされたファイルを検証する場合は、ファイル検証のために特別に作成されたルールを使用する必要があります。

重要

以下の表にリストされているルールのみをファイルの検証に使用できます。したがって、permit_empty のような一般的なルールをファイル検証ルールの配列または文字列に追加すると、ファイルの検証は正しく機能しません。

ファイルアップロードHTMLフィールドの値は存在せず、$_FILES グローバルに格納されているため、入力フィールドの名前を2回使用する必要があります。1回は他のルールと同様にフィールド名を指定するため、もう1回はすべてのファイルアップロード関連ルールの最初のパラメータとして使用します。

// In the HTML
<input type="file" name="avatar">

// In the controller
$this->validate([
    'avatar' => 'uploaded[avatar]|max_size[avatar,1024]',
]);

ルール

パラメータ

説明

uploaded

はい

パラメータの名前が、アップロードされたファイルの名前と一致しない場合に失敗します。ファイルアップロードをオプション(必須ではない)にしたい場合は、このルールを定義しないでください。

uploaded[field_name]

max_size

はい

パラメータで指定されたアップロードファイルが、2番目のパラメータ(キロバイト(kb)単位)より大きい場合、またはファイルがphp.ini設定ファイルで宣言された許容最大サイズ - upload_max_filesize ディレクティブ - より大きい場合に失敗します。

max_size[field_name,2048]

max_dims

はい

アップロードされた画像の最大幅と高さが値を超える場合に失敗します。最初のパラメータはフィールド名です。2番目は幅、3番目は高さです。ファイルが画像であると判断できない場合も失敗します。

max_dims[field_name,300,150]

mime_in

はい

ファイルのMIMEタイプがパラメータにリストされているものでない場合に失敗します。

mime_in[field_name,image/png,image/jpeg]

ext_in

はい

ファイルの拡張子がパラメータにリストされているものでない場合に失敗します。

ext_in[field_name,png,jpg,gif]

is_image

はい

MIMEタイプに基づいてファイルが画像であると判断できない場合に失敗します。

is_image[field_name]

ファイル検証ルールは、単一および複数のファイルアップロードの両方に適用されます。