検証
CodeIgniterは、記述するコード量を最小限に抑えるのに役立つ包括的なデータ検証クラスを提供します。
概要
CodeIgniterのデータ検証アプローチを説明する前に、理想的なシナリオを説明しましょう。
フォームが表示されます。
フォームに入力して送信します。
無効なものを送信した場合、または必須項目を忘れた場合、フォームは問題点を説明するエラーメッセージとともにデータを含めて再表示されます。
このプロセスは、有効なフォームを送信するまで続きます。
受信側では、スクリプトは次のことを行う必要があります。
必須データの確認。
データが正しいタイプであり、正しい基準を満たしていることを検証します。たとえば、ユーザー名が送信された場合、許可された文字のみが含まれるように検証する必要があります。最小の長さで、最大長を超えてはなりません。ユーザー名は他の既存のユーザー名にすることはできず、予約語にすることもできません。など。
セキュリティのためにデータをサニタイズします。
必要に応じてデータを事前フォーマットします。
データベースに挿入するデータを準備します。
上記プロセスについて特に複雑なことはありませんが、通常はかなりの量のコードが必要となり、エラーメッセージを表示するには、通常、さまざまな制御構造がフォームHTML内に配置されます。フォーム検証は、作成は簡単ですが、実装は一般的に非常に面倒で退屈です。
フォーム検証チュートリアル
以下は、CodeIgniterのフォーム検証を実装するための「ハンズオン」チュートリアルです。
フォーム検証を実装するには、次の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フォームです
フォームヘルパーを使用して、フォームの開始と終了を作成します。技術的には、これは必須ではありません。標準のHTMLを使用してフォームを作成できます。ただし、ヘルパーを使用する利点は、設定ファイルのURLに基づいてアクションURLを生成してくれることです。これにより、URLが変更された場合にアプリケーションの移植性が向上します。
フォームの先頭に、次の関数呼び出しが表示されます
<?= 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つのパラメータが必要です。
検証する値(
$value
)パラメータ文字列(
$params
)フォームで送信されたすべてのデータを含む配列(
$data
)(オプション)カスタムエラー文字列(
&$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 |
はい |
フィールドがパラメータ内のものと異なる場合、失敗します。 |
|
exact_length |
はい |
フィールドがパラメータ値とまったく異なる場合、失敗します。1つ以上のコンマ区切り値。 |
|
greater_than |
はい |
フィールドがパラメータ値以下の場合、または数値でない場合、失敗します。 |
|
greater_than_equal_to |
はい |
フィールドがパラメータ値より小さい場合、または数値でない場合、失敗します。 |
|
hex |
なし |
フィールドに16進数文字以外のものが含まれている場合、失敗します。 |
|
if_exist |
なし |
このルールが存在する場合、検証は検証するデータにフィールドキーが存在する場合にのみフィールドをチェックします。 |
|
in_list |
はい |
フィールドがあらかじめ決められたリスト内にない場合、失敗します。 |
|
integer |
なし |
フィールドに整数以外のものが含まれている場合、失敗します。 |
|
is_natural |
なし |
フィールドに自然数(0、1、2、3など)以外のものが含まれている場合、失敗します。 |
|
is_natural_no_zero |
なし |
フィールドにゼロ以外の自然数(1、2、3など)以外のものが含まれている場合、失敗します。 |
|
is_not_unique |
はい |
指定された値が存在するかどうかをデータベースで確認します。(現在、1つのフィルターのみを受け入れます)フィルタリングするフィールド/値でレコードを無視できます。 |
|
is_unique |
はい |
このフィールド値がデータベースに存在するかどうかを確認します。必要に応じて、無視する列と値を設定します。これは、レコード自体を無視するために更新する場合に役立ちます。 |
|
less_than |
はい |
フィールドがパラメータ値以上の場合、または数値でない場合、失敗します。 |
|
less_than_equal_to |
はい |
フィールドがパラメータ値より大きい場合、または数値でない場合、失敗します。 |
|
matches |
はい |
値は、パラメータ内のフィールドの値と一致する必要があります。 |
|
max_length |
はい |
フィールドがパラメータ値より長い場合、失敗します。 |
|
min_length |
はい |
フィールドがパラメータ値より短い場合、失敗します。 |
|
not_in_list |
はい |
フィールドがあらかじめ決められたリスト内にある場合、失敗します。 |
|
numeric |
なし |
フィールドに数値文字以外のものが含まれている場合、失敗します。 |
|
regex_match |
はい |
フィールドが正規表現に一致しない場合、失敗します。 |
|
permit_empty |
なし |
フィールドが空の配列、空の文字列、null、またはfalseを受け入れることができるようにします。 |
|
required |
なし |
フィールドが空の配列、空の文字列、null、またはfalseの場合、失敗します。 |
|
required_with |
はい |
データ内の他のフィールドが empty() でない場合に、このフィールドが必要になります。 |
|
required_without |
はい |
データ内の他のフィールドが empty() の場合に、このフィールドが必要になります。 |
|
string |
なし |
要素が文字列であることを確認する、alpha *ルールの一般的な代替。 |
|
timezone |
なし |
フィールドが timezone_identifiers_list() に従ってタイムゾーンと一致しない場合、失敗します。 |
|
valid_base64 |
なし |
フィールドに有効なBase64文字以外のものが含まれている場合、失敗します。 |
|
valid_json |
なし |
フィールドに有効なJSON文字列が含まれていない場合、失敗します。 |
|
valid_email |
なし |
フィールドに有効なメールアドレスが含まれていない場合、失敗します。 |
|
valid_emails |
なし |
コンマ区切りリストで提供された値に有効なメールが含まれていない場合、失敗します。 |
|
valid_ip |
はい |
指定されたIPが有効でない場合に失敗します。オプションのパラメータとして、IP形式を指定するために |
|
valid_url |
なし |
フィールドに(緩い)URLが含まれていない場合に失敗します。「codeigniter」のようなホスト名となりうる単純な文字列も含まれます。通常は、 |
|
valid_url_strict |
はい |
フィールドに有効なURLが含まれていない場合に失敗します。オプションで有効なスキーマのリストを指定できます。指定しない場合、 |
|
valid_date |
はい |
フィールドに有効な日付が含まれていない場合に失敗します。日付形式に一致させるためのオプションのパラメータを指定しない場合、strtotime() が受け入れる任意の文字列が有効です。そのため、通常はパラメータを指定する必要があります。 |
|
valid_cc_number |
はい |
クレジットカード番号が、指定されたプロバイダーが使用する形式に一致することを確認します。現在サポートされているプロバイダーは、American Express ( |
|
注意
また、少なくとも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 |
はい |
パラメータの名前が、アップロードされたファイルの名前と一致しない場合に失敗します。ファイルアップロードをオプション(必須ではない)にしたい場合は、このルールを定義しないでください。 |
|
max_size |
はい |
パラメータで指定されたアップロードファイルが、2番目のパラメータ(キロバイト(kb)単位)より大きい場合、またはファイルがphp.ini設定ファイルで宣言された許容最大サイズ - |
|
max_dims |
はい |
アップロードされた画像の最大幅と高さが値を超える場合に失敗します。最初のパラメータはフィールド名です。2番目は幅、3番目は高さです。ファイルが画像であると判断できない場合も失敗します。 |
|
mime_in |
はい |
ファイルのMIMEタイプがパラメータにリストされているものでない場合に失敗します。 |
|
ext_in |
はい |
ファイルの拡張子がパラメータにリストされているものでない場合に失敗します。 |
|
is_image |
はい |
MIMEタイプに基づいてファイルが画像であると判断できない場合に失敗します。 |
|
ファイル検証ルールは、単一および複数のファイルアップロードの両方に適用されます。