その他のバリデーター
composer で直接利用できるバリデーターが多数あります。例:
webman/validation(推奨)
top-think/think-validate
respect/validation
バリデーター webman/validation
illuminate/validation をベースに、手動バリデーション、アノテーションバリデーション、パラメータレベルのバリデーション、再利用可能なルールセットを提供します。
インストール
composer require webman/validation
基本概念
- ルールセットの再利用:
support\validation\Validatorを継承して再利用可能なrules、messages、attributes、scenesを定義でき、手動バリデーションとアノテーションバリデーションの両方で再利用できます。 - メソッドレベルのアノテーション(属性)バリデーション: PHP 8 属性
#[Validate]でコントローラーメソッドにバリデーションをバインドします。 - パラメータレベルのアノテーション(属性)バリデーション: PHP 8 属性
#[Param]でコントローラーメソッドのパラメータにバリデーションをバインドします。 - 例外処理: バリデーション失敗時に
support\validation\ValidationExceptionをスローします。例外クラスは設定可能です。 - データベースバリデーション: データベースバリデーションを行う場合は、
composer require webman/databaseのインストールが必要です。
手動バリデーション
基本的な使い方
use support\validation\Validator;
$data = ['email' => 'user@example.com'];
Validator::make($data, [
'email' => 'required|email',
])->validate();
注意
validate()はバリデーション失敗時にsupport\validation\ValidationExceptionをスローします。例外をスローしたくない場合は、以下のfails()方式でエラーメッセージを取得してください。
カスタムメッセージと属性
use support\validation\Validator;
$data = ['contact' => 'user@example.com'];
Validator::make(
$data,
['contact' => 'required|email'],
['contact.email' => 'Invalid email format'],
['contact' => 'Email']
)->validate();
例外をスローしないバリデーション(エラーメッセージの取得)
例外をスローしたくない場合は、fails() でチェックし、errors() 経由でエラーメッセージを取得します(MessageBag を返します):
use support\validation\Validator;
$data = ['email' => 'bad-email'];
$validator = Validator::make($data, [
'email' => 'required|email',
]);
if ($validator->fails()) {
$firstError = $validator->errors()->first(); // string
$allErrors = $validator->errors()->all(); // array
$errorsByField = $validator->errors()->toArray(); // array
// handle errors...
}
ルールセットの再利用(カスタムバリデーター)
namespace app\validation;
use support\validation\Validator;
class UserValidator extends Validator
{
protected array $rules = [
'id' => 'required|integer|min:1',
'name' => 'required|string|min:2|max:20',
'email' => 'required|email',
];
protected array $messages = [
'name.required' => 'Name is required',
'email.required' => 'Email is required',
'email.email' => 'Invalid email format',
];
protected array $attributes = [
'name' => 'Name',
'email' => 'Email',
];
}
手動バリデーションでの再利用
use app\validation\UserValidator;
UserValidator::make($data)->validate();
シーンの使用(オプション)
scenes はオプション機能です。withScene(...) を呼び出すと、フィールドのサブセットのみをバリデーションします。
namespace app\validation;
use support\validation\Validator;
class UserValidator extends Validator
{
protected array $rules = [
'id' => 'required|integer|min:1',
'name' => 'required|string|min:2|max:20',
'email' => 'required|email',
];
protected array $scenes = [
'create' => ['name', 'email'],
'update' => ['id', 'name', 'email'],
];
}
use app\validation\UserValidator;
// シーン未指定 -> 全ルールをバリデーション
UserValidator::make($data)->validate();
// シーン指定 -> そのシーンのフィールドのみバリデーション
UserValidator::make($data)->withScene('create')->validate();
アノテーションバリデーション(メソッドレベル)
直接ルール指定
use support\Request;
use support\validation\annotation\Validate;
class AuthController
{
#[Validate(
rules: [
'email' => 'required|email',
'password' => 'required|string|min:6',
],
messages: [
'email.required' => 'Email is required',
'password.required' => 'Password is required',
],
attributes: [
'email' => 'Email',
'password' => 'Password',
]
)]
public function login(Request $request)
{
return json(['code' => 0, 'msg' => 'ok']);
}
}
ルールセットの再利用
use app\validation\UserValidator;
use support\Request;
use support\validation\annotation\Validate;
class UserController
{
#[Validate(validator: UserValidator::class, scene: 'create')]
public function create(Request $request)
{
return json(['code' => 0, 'msg' => 'ok']);
}
}
複数バリデーションの重ね合わせ
use support\validation\annotation\Validate;
class UserController
{
#[Validate(rules: ['email' => 'required|email'])]
#[Validate(rules: ['token' => 'required|string'])]
public function send()
{
return json(['code' => 0, 'msg' => 'ok']);
}
}
バリデーションデータソース
use support\validation\annotation\Validate;
class UserController
{
#[Validate(
rules: ['email' => 'required|email'],
in: ['query', 'body', 'path']
)]
public function send()
{
return json(['code' => 0, 'msg' => 'ok']);
}
}
in パラメータでデータソースを指定します:
- query HTTP リクエストのクエリパラメータ(
$request->get()から) - body HTTP リクエストボディ(
$request->post()から) - path HTTP リクエストのパスパラメータ(
$request->route->param()から)
in は文字列または配列にできます。配列の場合は、後続の値が前の値を上書きする形でマージされます。in を渡さない場合、デフォルトは ['query', 'body', 'path'] です。
パラメータレベルのバリデーション(Param)
基本的な使い方
use support\validation\annotation\Param;
class MailController
{
public function send(
#[Param(rules: 'required|email')] string $from,
#[Param(rules: 'required|email')] string $to,
#[Param(rules: 'required|string|min:1|max:500')] string $content
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
バリデーションデータソース
同様に、パラメータレベルのバリデーションでも in パラメータでソースを指定できます:
use support\validation\annotation\Param;
class MailController
{
public function send(
#[Param(rules: 'required|email', in: ['body'])] string $from
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
rules は文字列または配列をサポート
use support\validation\annotation\Param;
class MailController
{
public function send(
#[Param(rules: ['required', 'email'])] string $from
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
カスタムメッセージ / 属性
use support\validation\annotation\Param;
class UserController
{
public function updateEmail(
#[Param(
rules: 'required|email',
messages: ['email.email' => 'Invalid email format'],
attribute: 'Email'
)]
string $email
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
ルール定数の再利用
final class ParamRules
{
public const EMAIL = ['required', 'email'];
}
class UserController
{
public function send(
#[Param(rules: ParamRules::EMAIL)] string $email
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
メソッドレベル + パラメータレベルの併用
use support\Request;
use support\validation\annotation\Param;
use support\validation\annotation\Validate;
class UserController
{
#[Validate(rules: ['token' => 'required|string'])]
public function send(
Request $request,
#[Param(rules: 'required|email')] string $from,
#[Param(rules: 'required|integer')] int $id
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
自動ルール推論(パラメータシグネチャベース)
メソッドに #[Validate] が使われている場合、またはそのメソッドのいずれかのパラメータが #[Param] を使っている場合、このコンポーネントはメソッドのパラメータシグネチャから基本的なバリデーションルールを自動推論して補完し、既存のルールとマージしてからバリデーションを行います。
例:#[Validate] の等価な展開
1) #[Validate] のみ有効で、ルールを手動で書かない場合:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate]
public function create(string $content, int $uid)
{
}
}
以下と等価:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'required|string',
'uid' => 'required|integer',
])]
public function create(string $content, int $uid)
{
}
}
2) 一部のルールのみ記述し、残りはパラメータシグネチャで補完する場合:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'min:2',
])]
public function create(string $content, int $uid)
{
}
}
以下と等価:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'required|string|min:2',
'uid' => 'required|integer',
])]
public function create(string $content, int $uid)
{
}
}
3) デフォルト値 / ヌラブル型:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate]
public function create(string $content = 'default', ?int $uid = null)
{
}
}
以下と等価:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'string',
'uid' => 'integer|nullable',
])]
public function create(string $content = 'default', ?int $uid = null)
{
}
}
例外処理
デフォルトの例外
バリデーション失敗時は、デフォルトで support\validation\ValidationException がスローされます。この例外は Webman\Exception\BusinessException を継承しており、エラーはログされません。
デフォルトのレスポンス動作は BusinessException::render() で処理されます:
- 通常リクエスト:文字列メッセージを返す(例:
token is required.) - JSON リクエスト:JSON レスポンスを返す(例:
{"code": 422, "msg": "token is required.", "data":....})
カスタム例外によるカスタマイズ
- グローバル設定:
config/plugin/webman/validation/app.phpのexception
多言語対応
このコンポーネントには中国語と英語の言語パックが組み込まれており、プロジェクトでの上書きをサポートしています。読み込み順序:
- プロジェクトの言語パック
resource/translations/{locale}/validation.php - コンポーネント組み込み
vendor/webman/validation/resources/lang/{locale}/validation.php - Illuminate 組み込みの英語(フォールバック)
注意
Webman のデフォルト言語はconfig/translation.phpで設定するか、locale('en');で変更できます。
ローカル上書きの例
resource/translations/zh_CN/validation.php
return [
'email' => ':attribute is not a valid email format.',
];
ミドルウェアの自動読み込み
インストール後、コンポーネントは config/plugin/webman/validation/middleware.php 経由でバリデーションミドルウェアを自動読み込みします。手動登録は不要です。
コマンドライン生成
make:validator コマンドでバリデータークラスを生成します(デフォルト出力先は app/validation ディレクトリ)。
注意
composer require webman/consoleが必要です
基本的な使い方
- 空のテンプレートを生成
php webman make:validator UserValidator
- 既存ファイルを上書き
php webman make:validator UserValidator --force
php webman make:validator UserValidator -f
テーブル構造からルールを生成
- テーブル名を指定して基本ルールを生成(フィールド型 / nullable / 長さなどから
$rulesを推論;デフォルトで ORM 関連フィールドを除外:laravel はcreated_at/updated_at/deleted_at、thinkorm はcreate_time/update_time/delete_time)
php webman make:validator UserValidator --table=wa_users
php webman make:validator UserValidator -t wa_users
- データベース接続を指定(マルチ接続時)
php webman make:validator UserValidator --table=wa_users --database=mysql
php webman make:validator UserValidator -t wa_users -d mysql
シーン
- CRUD シーンを生成:
create/update/delete/detail
php webman make:validator UserValidator --table=wa_users --scenes=crud
php webman make:validator UserValidator -t wa_users -s crud
updateシーンには主キーフィールド(レコード特定用)とその他のフィールドが含まれます。delete/detailはデフォルトで主キーのみ含みます。
ORM 選択(laravel (illuminate/database) vs think-orm)
- 自動選択(デフォルト): インストール・設定されているものを使用。両方ある場合は illuminate をデフォルトで使用
- 強制指定
php webman make:validator UserValidator --table=wa_users --orm=laravel
php webman make:validator UserValidator --table=wa_users --orm=thinkorm
php webman make:validator UserValidator -t wa_users -o thinkorm
完全な例
php webman make:validator UserValidator -t wa_users -d mysql -s crud -o laravel -f
ユニットテスト
webman/validation のルートディレクトリで実行:
composer install
vendor\bin\phpunit -c phpunit.xml
バリデーションルールリファレンス
利用可能なバリデーションルール
[!IMPORTANT]
- Webman Validation は
illuminate/validationをベースとしており、ルール名は Laravel と一致し、Webman 固有のルールはありません。- ミドルウェアはデフォルトで
$request->all()(GET+POST)とルートパラメータをマージしたデータをバリデーションし、アップロードファイルは除外します。ファイルルールの場合は、$request->file()をデータにマージするか、Validator::makeを手動で呼び出してください。current_passwordは認証ガードに依存し、exists/uniqueはデータベース接続とクエリビルダーに依存します。対応するコンポーネントが統合されていない場合、これらのルールは使用できません。
以下に、利用可能なバリデーションルールとその用途を一覧します:
Boolean(真偽値)
String(文字列)
Numeric(数値)
Array(配列)
Date(日付)
File(ファイル)
Database(データベース)
Utility(ユーティリティ)
accepted
フィールドは "yes"、"on"、1、"1"、true、または "true" である必要があります。利用規約への同意確認などのシナリオでよく使われます。
accepted_if:anotherfield,value,...
別のフィールドが指定値と等しい場合、このフィールドは "yes"、"on"、1、"1"、true、または "true" である必要があります。条件付き同意のシナリオでよく使われます。
active_url
フィールドは有効な A または AAAA レコードを持つ必要があります。このルールはまず parse_url で URL のホスト名を抽出し、dns_get_record でバリデーションします。
after:date
フィールドは指定日付より後の値である必要があります。日付は strtotime に渡して有効な DateTime に変換されます:
use support\validation\Validator;
Validator::make($data, [
'start_date' => 'required|date|after:tomorrow',
])->validate();
比較用に別のフィールド名を渡すこともできます:
Validator::make($data, [
'finish_date' => 'required|date|after:start_date',
])->validate();
fluent な date ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->after(\Carbon\Carbon::today()->addDays(7)),
],
])->validate();
afterToday と todayOrAfter で「今日より後である必要がある」「今日以降である必要がある」を簡潔に表現できます:
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->afterToday(),
],
])->validate();
after_or_equal:date
フィールドは指定日付当日またはそれ以降である必要があります。詳細は after を参照してください。
fluent な date ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->afterOrEqual(\Carbon\Carbon::today()->addDays(7)),
],
])->validate();
anyOf
Rule::anyOf で「いずれか一つのルールセットを満たす」を指定できます。例えば、以下のルールは username がメールアドレスであるか、6 文字以上の英数字・アンダースコア・ハイフンの文字列である必要があることを意味します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'username' => [
'required',
Rule::anyOf([
['string', 'email'],
['string', 'alpha_dash', 'min:6'],
]),
],
])->validate();
alpha
フィールドは Unicode 文字(\p{L} と \p{M})である必要があります。
ASCII(a-z、A-Z)のみ許可するには、ascii オプションを追加します:
Validator::make($data, [
'username' => 'alpha:ascii',
])->validate();
alpha_dash
フィールドは Unicode の文字と数字(\p{L}、\p{M}、\p{N})と ASCII のハイフン(-)およびアンダースコア(_)のみを含むことができます。
ASCII(a-z、A-Z、0-9)のみ許可するには、ascii オプションを追加します:
Validator::make($data, [
'username' => 'alpha_dash:ascii',
])->validate();
alpha_num
フィールドは Unicode の文字と数字(\p{L}、\p{M}、\p{N})のみを含むことができます。
ASCII(a-z、A-Z、0-9)のみ許可するには、ascii オプションを追加します:
Validator::make($data, [
'username' => 'alpha_num:ascii',
])->validate();
array
フィールドは PHP の array である必要があります。
array ルールに追加パラメータがある場合、入力配列のキーはパラメータリストに含まれる必要があります。例では admin キーが許可リストにないため無効です:
use support\validation\Validator;
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
Validator::make($input, [
'user' => 'array:name,username',
])->validate();
実際のプロジェクトでは、許可する配列キーを明示的に定義することを推奨します。
ascii
フィールドは 7 ビット ASCII 文字のみを含むことができます。
bail
フィールドの最初のルールが失敗した時点で、それ以降のルールのバリデーションを停止します。
このルールは現在のフィールドにのみ影響します。「最初の失敗でグローバルに停止」するには、Illuminate のバリデーターを直接使用して stopOnFirstFailure() を呼び出してください。
before:date
フィールドは指定日付より前である必要があります。日付は strtotime に渡して有効な DateTime に変換されます。after と同様に、比較用に別のフィールド名を渡せます。
fluent な date ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->before(\Carbon\Carbon::today()->subDays(7)),
],
])->validate();
beforeToday と todayOrBefore で「今日より前である必要がある」「今日以前である必要がある」を簡潔に表現できます:
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->beforeToday(),
],
])->validate();
before_or_equal:date
フィールドは指定日付当日またはそれ以前である必要があります。日付は strtotime に渡して有効な DateTime に変換されます。after と同様に、比較用に別のフィールド名を渡せます。
fluent な date ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->beforeOrEqual(\Carbon\Carbon::today()->subDays(7)),
],
])->validate();
between:min,max
フィールドのサイズは min 以上 max 以下である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
boolean
フィールドは真偽値に変換可能である必要があります。許容される入力には true、false、1、0、"1"、"0" が含まれます。
strict パラメータで true または false のみ許可できます:
Validator::make($data, [
'foo' => 'boolean:strict',
])->validate();
confirmed
フィールドには一致する {field}_confirmation フィールドが必要です。例えば、フィールドが password の場合、password_confirmation が必要です。
カスタム確認フィールド名も指定できます。例:confirmed:repeat_username は repeat_username が現在のフィールドと一致する必要があります。
contains:foo,bar,...
フィールドは配列であり、指定されたパラメータ値をすべて含む必要があります。このルールは配列バリデーションでよく使われます。Rule::contains で構築できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'roles' => [
'required',
'array',
Rule::contains(['admin', 'editor']),
],
])->validate();
doesnt_contain:foo,bar,...
フィールドは配列であり、指定されたパラメータ値のいずれも含んではいけません。Rule::doesntContain で構築できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'roles' => [
'required',
'array',
Rule::doesntContain(['admin', 'editor']),
],
])->validate();
current_password
フィールドは現在認証されているユーザーのパスワードと一致する必要があります。最初のパラメータで認証ガードを指定できます:
Validator::make($data, [
'password' => 'current_password:api',
])->validate();
[!WARNING]
このルールは認証コンポーネントとガード設定に依存します。認証が統合されていない場合は使用しないでください。
date
フィールドは strtotime で認識可能な有効な(相対的でない)日付である必要があります。
date_equals:date
フィールドは指定日付と等しい必要があります。日付は strtotime に渡して有効な DateTime に変換されます。
date_format:format,...
フィールドは指定されたフォーマットのいずれかに一致する必要があります。date または date_format のいずれかを使用してください。このルールは PHP の DateTime の全フォーマットをサポートします。
fluent な date ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->format('Y-m-d'),
],
])->validate();
decimal:min,max
フィールドは必要な小数桁を持つ数値である必要があります:
Validator::make($data, [
'price' => 'decimal:2',
])->validate();
Validator::make($data, [
'price' => 'decimal:2,4',
])->validate();
declined
フィールドは "no"、"off"、0、"0"、false、または "false" である必要があります。
declined_if:anotherfield,value,...
別のフィールドが指定値と等しい場合、このフィールドは "no"、"off"、0、"0"、false、または "false" である必要があります。
different:field
フィールドは field と異なる必要があります。
digits:value
フィールドは長さ value の整数である必要があります。
digits_between:min,max
フィールドは長さが min 以上 max 以下の整数である必要があります。
dimensions
フィールドは画像であり、寸法制約を満たす必要があります:
Validator::make($data, [
'avatar' => 'dimensions:min_width=100,min_height=200',
])->validate();
利用可能な制約:min_width、max_width、min_height、max_height、width、height、ratio。
ratio はアスペクト比です。分数または浮動小数で表現できます:
Validator::make($data, [
'avatar' => 'dimensions:ratio=3/2',
])->validate();
このルールには多くのパラメータがあるため、Rule::dimensions で構築することを推奨します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()
->maxWidth(1000)
->maxHeight(500)
->ratio(3 / 2),
],
])->validate();
distinct
配列をバリデーションする際、フィールド値が重複してはいけません:
Validator::make($data, [
'foo.*.id' => 'distinct',
])->validate();
デフォルトでは緩い比較を使用します。厳密比較には strict を追加します:
Validator::make($data, [
'foo.*.id' => 'distinct:strict',
])->validate();
大文字小文字の違いを無視するには ignore_case を追加します:
Validator::make($data, [
'foo.*.id' => 'distinct:ignore_case',
])->validate();
doesnt_start_with:foo,bar,...
フィールドは指定された値のいずれでも始まってはいけません。
doesnt_end_with:foo,bar,...
フィールドは指定された値のいずれでも終わってはいけません。
フィールドは有効なメールアドレスである必要があります。このルールは egulias/email-validator に依存し、デフォルトで RFCValidation を使用し、他のバリデーション方式も使用できます:
Validator::make($data, [
'email' => 'email:rfc,dns',
])->validate();
利用可能なバリデーション方式:
fluent ルールビルダーを使用できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
'required',
Rule::email()
->rfcCompliant(strict: false)
->validateMxRecord()
->preventSpoofing(),
],
])->validate();
[!WARNING]
dnsとspoofには PHP のintl拡張が必要です。
encoding:encoding_type
フィールドは指定された文字エンコーディングに一致する必要があります。このルールは mb_check_encoding でファイルまたは文字列のエンコーディングを検出します。ファイルルールビルダーと併用できます:
use Illuminate\Validation\Rules\File;
use support\validation\Validator;
Validator::make($data, [
'attachment' => [
'required',
File::types(['csv'])->encoding('utf-8'),
],
])->validate();
ends_with:foo,bar,...
フィールドは指定された値のいずれかで終わる必要があります。
enum
Enum は、フィールド値が有効な enum 値であることをバリデーションするクラスベースのルールです。構築時に enum クラス名を渡します。プリミティブ値の場合は Backed Enum を使用します:
use app\enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'status' => [Rule::enum(ServerStatus::class)],
])->validate();
only/except で enum 値を制限できます:
use app\enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'status' => [
Rule::enum(ServerStatus::class)
->only([ServerStatus::Pending, ServerStatus::Active]),
],
])->validate();
Validator::make($data, [
'status' => [
Rule::enum(ServerStatus::class)
->except([ServerStatus::Pending, ServerStatus::Active]),
],
])->validate();
条件付き制限には when を使用します:
use app\Enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'status' => [
Rule::enum(ServerStatus::class)->when(
$isAdmin,
fn ($rule) => $rule->only(ServerStatus::Active),
fn ($rule) => $rule->only(ServerStatus::Pending),
),
],
])->validate();
exclude
フィールドは validate/validated が返すデータから除外されます。
exclude_if:anotherfield,value
anotherfield が value と等しい場合、フィールドは validate/validated が返すデータから除外されます。
複雑な条件には Rule::excludeIf を使用します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'role_id' => Rule::excludeIf($isAdmin),
])->validate();
Validator::make($data, [
'role_id' => Rule::excludeIf(fn () => $isAdmin),
])->validate();
exclude_unless:anotherfield,value
anotherfield が value と等しくない限り、フィールドは validate/validated が返すデータから除外されます。value が null(例:exclude_unless:name,null)の場合、比較フィールドが null または存在しない場合のみフィールドが保持されます。
exclude_with:anotherfield
anotherfield が存在する場合、フィールドは validate/validated が返すデータから除外されます。
exclude_without:anotherfield
anotherfield が存在しない場合、フィールドは validate/validated が返すデータから除外されます。
exists:table,column
フィールドは指定されたデータベーステーブルに存在する必要があります。
Exists ルールの基本的な使い方
Validator::make($data, [
'state' => 'exists:states',
])->validate();
column を指定しない場合、デフォルトでフィールド名が使われます。この例では states テーブルの state カラムが存在するかバリデーションします。
カスタムカラム名の指定
テーブル名の後にカラム名を付けます:
Validator::make($data, [
'state' => 'exists:states,abbreviation',
])->validate();
データベース接続を指定するには、テーブル名の前に接続名を付けます:
Validator::make($data, [
'email' => 'exists:connection.staff,email',
])->validate();
モデルクラス名を渡すこともできます。フレームワークがテーブル名を解決します:
Validator::make($data, [
'user_id' => 'exists:app\model\User,id',
])->validate();
カスタムクエリ条件には Rule ビルダーを使用します:
use Illuminate\Database\Query\Builder;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
'required',
Rule::exists('staff')->where(function (Builder $query) {
$query->where('account_id', 1);
}),
],
])->validate();
Rule::exists で直接カラム名を指定することもできます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'state' => [Rule::exists('states', 'abbreviation')],
])->validate();
複数の値の存在をバリデーションするには、array ルールと組み合わせます:
Validator::make($data, [
'states' => ['array', Rule::exists('states', 'abbreviation')],
])->validate();
array と exists の両方がある場合、1 回のクエリで全値をバリデーションします。
extensions:foo,bar,...
アップロードされたファイルの拡張子が許可リストに含まれることをバリデーションします:
Validator::make($data, [
'photo' => ['required', 'extensions:jpg,png'],
])->validate();
[!WARNING]
ファイルタイプのバリデーションに拡張子のみに頼らないでください。mimes または mimetypes と併用してください。
file
フィールドは正常にアップロードされたファイルである必要があります。
filled
フィールドが存在する場合、その値は空であってはいけません。
gt:field
フィールドは指定された field または value より大きい必要があります。両方のフィールドは同じ型である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
gte:field
フィールドは指定された field または value 以上である必要があります。両方のフィールドは同じ型である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
hex_color
フィールドは有効な hex color value である必要があります。
image
フィールドは画像(jpg、jpeg、png、bmp、gif、webp)である必要があります。
[!WARNING]
XSS リスクのため、SVG はデフォルトで許可されていません。許可するにはallow_svgを追加します:image:allow_svg。
in:foo,bar,...
フィールドは指定された値リストに含まれる必要があります。Rule::in で構築できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
])->validate();
array ルールと組み合わせると、入力配列の各値が in リストに含まれる必要があります:
use support\validation\Rule;
use support\validation\Validator;
$input = [
'airports' => ['NYC', 'LAS'],
];
Validator::make($input, [
'airports' => [
'required',
'array',
],
'airports.*' => Rule::in(['NYC', 'LIT']),
])->validate();
in_array:anotherfield.*
フィールドは anotherfield の値リストに存在する必要があります。
in_array_keys:value.*
フィールドは配列であり、指定された値のいずれかをキーとして含む必要があります:
Validator::make($data, [
'config' => 'array|in_array_keys:timezone',
])->validate();
integer
フィールドは整数である必要があります。
strict パラメータでフィールド型が integer であることを要求できます。文字列の整数は無効になります:
Validator::make($data, [
'age' => 'integer:strict',
])->validate();
[!WARNING]
このルールは PHP のFILTER_VALIDATE_INTを通過するかどうかのみをバリデーションします。厳密な数値型には numeric と併用してください。
ip
フィールドは有効な IP アドレスである必要があります。
ipv4
フィールドは有効な IPv4 アドレスである必要があります。
ipv6
フィールドは有効な IPv6 アドレスである必要があります。
json
フィールドは有効な JSON 文字列である必要があります。
lt:field
フィールドは指定された field より小さい必要があります。両方のフィールドは同じ型である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
lte:field
フィールドは指定された field 以下である必要があります。両方のフィールドは同じ型である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
lowercase
フィールドは小文字である必要があります。
list
フィールドはリスト配列である必要があります。リスト配列のキーは 0 から count($array) - 1 までの連続した数値である必要があります。
mac_address
フィールドは有効な MAC アドレスである必要があります。
max:value
フィールドは value 以下である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
max_digits:value
フィールドは長さが value を超えない整数である必要があります。
mimetypes:text/plain,...
ファイルの MIME タイプがリストに含まれることをバリデーションします:
Validator::make($data, [
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime',
])->validate();
MIME タイプはファイル内容を読み取って推測され、クライアント提供の MIME と異なる場合があります。
mimes:foo,bar,...
ファイルの MIME タイプが指定された拡張子に対応することをバリデーションします:
Validator::make($data, [
'photo' => 'mimes:jpg,bmp,png',
])->validate();
パラメータは拡張子ですが、このルールはファイル内容を読み取って MIME を判定します。拡張子と MIME のマッピング:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
MIME タイプと拡張子
このルールは「ファイル拡張子」が「実際の MIME」と一致することをバリデーションしません。例えば、mimes:png は PNG 内容の photo.txt を有効とします。拡張子をバリデーションするには extensions を使用してください。
min:value
フィールドは value 以上である必要があります。文字列、数値、配列、ファイルの評価は size と同じです。
min_digits:value
フィールドは長さが value 未満でない整数である必要があります。
multiple_of:value
フィールドは value の倍数である必要があります。
missing
フィールドは入力データに存在してはいけません。
missing_if:anotherfield,value,...
anotherfield が任意の value と等しい場合、フィールドは存在してはいけません。
missing_unless:anotherfield,value
anotherfield が任意の value と等しくない限り、フィールドは存在してはいけません。
missing_with:foo,bar,...
指定されたいずれかのフィールドが存在する場合、フィールドは存在してはいけません。
missing_with_all:foo,bar,...
指定されたすべてのフィールドが存在する場合、フィールドは存在してはいけません。
not_in:foo,bar,...
フィールドは指定された値リストに含まれてはいけません。Rule::notIn で構築できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
])->validate();
not_regex:pattern
フィールドは指定された正規表現に一致してはいけません。
このルールは PHP の preg_match を使用します。正規表現には区切り文字が必要です。例:'email' => 'not_regex:/^.+$/i'。
[!WARNING]
regex/not_regexを使用する際、正規表現に|が含まれる場合は、|区切り文字との衝突を避けるため配列形式を使用してください。
nullable
フィールドは null でも構いません。
numeric
フィールドは numeric である必要があります。
strict パラメータで integer または float 型のみ許可できます。数値文字列は無効になります:
Validator::make($data, [
'amount' => 'numeric:strict',
])->validate();
present
フィールドは入力データに存在する必要があります。
present_if:anotherfield,value,...
anotherfield が任意の value と等しい場合、フィールドは存在する必要があります。
present_unless:anotherfield,value
anotherfield が任意の value と等しくない限り、フィールドは存在する必要があります。
present_with:foo,bar,...
指定されたいずれかのフィールドが存在する場合、フィールドは存在する必要があります。
present_with_all:foo,bar,...
指定されたすべてのフィールドが存在する場合、フィールドは存在する必要があります。
prohibited
フィールドは存在しないか、空である必要があります。「空」とは:
prohibited_if:anotherfield,value,...
anotherfield が任意の value と等しい場合、フィールドは存在しないか空である必要があります。「空」とは:
複雑な条件には Rule::prohibitedIf を使用します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'role_id' => Rule::prohibitedIf($isAdmin),
])->validate();
Validator::make($data, [
'role_id' => Rule::prohibitedIf(fn () => $isAdmin),
])->validate();
prohibited_if_accepted:anotherfield,...
anotherfield が "yes"、"on"、1、"1"、true、または "true" の場合、フィールドは存在しないか空である必要があります。
prohibited_if_declined:anotherfield,...
anotherfield が "no"、"off"、0、"0"、false、または "false" の場合、フィールドは存在しないか空である必要があります。
prohibited_unless:anotherfield,value,...
anotherfield が任意の value と等しくない限り、フィールドは存在しないか空である必要があります。「空」とは:
prohibits:anotherfield,...
フィールドが存在し空でない場合、anotherfield のすべてのフィールドは存在しないか空である必要があります。「空」とは:
regex:pattern
フィールドは指定された正規表現に一致する必要があります。
このルールは PHP の preg_match を使用します。正規表現には区切り文字が必要です。例:'email' => 'regex:/^.+@.+$/i'。
[!WARNING]
regex/not_regexを使用する際、正規表現に|が含まれる場合は、|区切り文字との衝突を避けるため配列形式を使用してください。
required
フィールドは存在し、空であってはいけません。「空」とは:
required_if:anotherfield,value,...
anotherfield が任意の value と等しい場合、フィールドは存在し空であってはいけません。
複雑な条件には Rule::requiredIf を使用します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'role_id' => Rule::requiredIf($isAdmin),
])->validate();
Validator::make($data, [
'role_id' => Rule::requiredIf(fn () => $isAdmin),
])->validate();
required_if_accepted:anotherfield,...
anotherfield が "yes"、"on"、1、"1"、true、または "true" の場合、フィールドは存在し空であってはいけません。
required_if_declined:anotherfield,...
anotherfield が "no"、"off"、0、"0"、false、または "false" の場合、フィールドは存在し空であってはいけません。
required_unless:anotherfield,value,...
anotherfield が任意の value と等しくない限り、フィールドは存在し空であってはいけません。value が null(例:required_unless:name,null)の場合、比較フィールドが null または存在しない場合のみフィールドを空にできます。
required_with:foo,bar,...
指定されたいずれかのフィールドが存在し空でない場合、フィールドは存在し空であってはいけません。
required_with_all:foo,bar,...
指定されたすべてのフィールドが存在し空でない場合、フィールドは存在し空であってはいけません。
required_without:foo,bar,...
指定されたいずれかのフィールドが空または存在しない場合、フィールドは存在し空であってはいけません。
required_without_all:foo,bar,...
指定されたすべてのフィールドが空または存在しない場合、フィールドは存在し空であってはいけません。
required_array_keys:foo,bar,...
フィールドは配列であり、指定されたキーを少なくとも含む必要があります。
sometimes
フィールドが存在する場合のみ、後続のバリデーションルールを適用します。「オプションだが存在する場合は有効である必要がある」フィールドでよく使われます:
Validator::make($data, [
'nickname' => 'sometimes|string|max:20',
])->validate();
same:field
フィールドは field と同じである必要があります。
size:value
フィールドのサイズは指定された value と等しい必要があります。文字列:文字数;数値:指定された整数(numeric または integer と併用);配列:要素数;ファイル:KB 単位のサイズ。例:
Validator::make($data, [
'title' => 'size:12',
'seats' => 'integer|size:10',
'tags' => 'array|size:5',
'image' => 'file|size:512',
])->validate();
starts_with:foo,bar,...
フィールドは指定された値のいずれかで始まる必要があります。
string
フィールドは文字列である必要があります。null を許可するには nullable と併用してください。
timezone
フィールドは有効なタイムゾーン識別子(DateTimeZone::listIdentifiers から)である必要があります。そのメソッドでサポートされるパラメータを渡せます:
Validator::make($data, [
'timezone' => 'required|timezone:all',
])->validate();
Validator::make($data, [
'timezone' => 'required|timezone:Africa',
])->validate();
Validator::make($data, [
'timezone' => 'required|timezone:per_country,US',
])->validate();
unique:table,column
フィールドは指定されたテーブルで一意である必要があります。
カスタムテーブル/カラム名の指定:
モデルクラス名を直接指定できます:
Validator::make($data, [
'email' => 'unique:app\model\User,email_address',
])->validate();
カラム名を指定できます(指定しない場合はデフォルトでフィールド名が使われます):
Validator::make($data, [
'email' => 'unique:users,email_address',
])->validate();
データベース接続の指定:
Validator::make($data, [
'email' => 'unique:connection.users,email_address',
])->validate();
指定 ID の除外:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
])->validate();
[!WARNING]
ignoreはユーザー入力を受け取るべきではありません。システム生成の一意 ID(自動増分 ID またはモデル UUID)のみを使用してください。そうでないと SQL インジェクションのリスクが存在する可能性があります。
モデルインスタンスを渡すこともできます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users')->ignore($user),
],
])->validate();
主キーが id でない場合は、主キー名を指定します:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users')->ignore($user->id, 'user_id'),
],
])->validate();
デフォルトではフィールド名が一意カラムとして使われます。カラム名も指定できます:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users', 'email_address')->ignore($user->id),
],
])->validate();
追加条件の指定:
use Illuminate\Database\Query\Builder;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users')->where(
fn (Builder $query) => $query->where('account_id', 1)
),
],
])->validate();
ソフトデリートレコードの除外:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [Rule::unique('users')->withoutTrashed()],
])->validate();
ソフトデリートカラムが deleted_at でない場合:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [Rule::unique('users')->withoutTrashed('was_deleted_at')],
])->validate();
uppercase
フィールドは大文字である必要があります。
url
フィールドは有効な URL である必要があります。
許可するプロトコルを指定できます:
Validator::make($data, [
'url' => 'url:http,https',
'game' => 'url:minecraft,steam',
])->validate();
ulid
フィールドは有効な ULID である必要があります。
uuid
フィールドは有効な RFC 9562 UUID(バージョン 1、3、4、5、6、7、または 8)である必要があります。
バージョンを指定できます:
Validator::make($data, [
'uuid' => 'uuid:4',
])->validate();
バリデーター top-think/think-validate
説明
ThinkPHP 公式バリデーター
プロジェクト URL
https://github.com/top-think/think-validate
インストール
composer require topthink/think-validate
クイックスタート
app/index/validate/User.php を作成
<?php
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => 'Name is required',
'name.max' => 'Name cannot exceed 25 characters',
'age.number' => 'Age must be a number',
'age.between' => 'Age must be between 1 and 120',
'email' => 'Invalid email format',
];
}
Usage
$data = [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com',
];
$validate = new \app\index\validate\User;
if (!$validate->check($data)) {
var_dump($validate->getError());
}
注意
webman は think-validate のValidate::rule()メソッドをサポートしていません
バリデーター workerman/validation
説明
このプロジェクトは https://github.com/Respect/Validation のローカライズ版です
プロジェクト URL
https://github.com/walkor/validation
インストール
composer require workerman/validation
クイックスタート
<?php
namespace app\controller;
use support\Request;
use Respect\Validation\Validator as v;
use support\Db;
class IndexController
{
public function index(Request $request)
{
$data = v::input($request->post(), [
'nickname' => v::length(1, 64)->setName('Nickname'),
'username' => v::alnum()->length(5, 64)->setName('Username'),
'password' => v::length(5, 64)->setName('Password')
]);
Db::table('user')->insert($data);
return json(['code' => 0, 'msg' => 'ok']);
}
}
Access via jQuery
$.ajax({
url : 'http://127.0.0.1:8787',
type : "post",
dataType:'json',
data : {nickname:'Tom', username:'tom cat', password: '123456'}
});
Result:
{"code":500,"msg":"Username may only contain letters (a-z) and numbers (0-9)"}
Explanation:
v::input(array $input, array $rules) はデータをバリデーションして収集します。バリデーション失敗時は Respect\Validation\Exceptions\ValidationException をスローし、成功時はバリデーション済みデータ(配列)を返します。
ビジネスコードがバリデーション例外をキャッチしない場合、webman フレームワークがキャッチして JSON({"code":500, "msg":"xxx"} のような形式)または通常の例外ページを HTTP ヘッダーに応じて返します。レスポンス形式が要件に合わない場合は、以下の例のように ValidationException をキャッチしてカスタムデータを返すことができます:
<?php
namespace app\controller;
use support\Request;
use Respect\Validation\Validator as v;
use Respect\Validation\Exceptions\ValidationException;
class IndexController
{
public function index(Request $request)
{
try {
$data = v::input($request->post(), [
'username' => v::alnum()->length(5, 64)->setName('Username'),
'password' => v::length(5, 64)->setName('Password')
]);
} catch (ValidationException $e) {
return json(['code' => 500, 'msg' => $e->getMessage()]);
}
return json(['code' => 0, 'msg' => 'ok', 'data' => $data]);
}
}
バリデーターガイド
use Respect\Validation\Validator as v;
// Single rule validation
$number = 123;
v::numericVal()->validate($number); // true
// Chained validation
$usernameValidator = v::alnum()->noWhitespace()->length(1, 15);
$usernameValidator->validate('alganet'); // true
// Get first validation failure reason
try {
$usernameValidator->setName('Username')->check('alg anet');
} catch (ValidationException $exception) {
echo $exception->getMessage(); // Username may only contain letters (a-z) and numbers (0-9)
}
// Get all validation failure reasons
try {
$usernameValidator->setName('Username')->assert('alg anet');
} catch (ValidationException $exception) {
echo $exception->getFullMessage();
// Will print
// - Username must satisfy the following rules
// - Username may only contain letters (a-z) and numbers (0-9)
// - Username must not contain whitespace
var_export($exception->getMessages());
// Will print
// array (
// 'alnum' => 'Username may only contain letters (a-z) and numbers (0-9)',
// 'noWhitespace' => 'Username must not contain whitespace',
// )
}
// Custom error messages
try {
$usernameValidator->setName('Username')->assert('alg anet');
} catch (ValidationException $exception) {
var_export($exception->getMessages([
'alnum' => 'Username may only contain letters and numbers',
'noWhitespace' => 'Username must not contain spaces',
'length' => 'length satisfies the rule, so this will not be shown'
]));
// Will print
// array(
// 'alnum' => 'Username may only contain letters and numbers',
// 'noWhitespace' => 'Username must not contain spaces'
// )
}
// Validate object
$user = new stdClass;
$user->name = 'Alexandre';
$user->birthdate = '1987-07-01';
$userValidator = v::attribute('name', v::stringType()->length(1, 32))
->attribute('birthdate', v::date()->minAge(18));
$userValidator->validate($user); // true
// Validate array
$data = [
'parentKey' => [
'field1' => 'value1',
'field2' => 'value2'
'field3' => true,
]
];
v::key(
'parentKey',
v::key('field1', v::stringType())
->key('field2', v::stringType())
->key('field3', v::boolType())
)
->assert($data); // Can also use check() or validate()
// Optional validation
v::alpha()->validate(''); // false
v::alpha()->validate(null); // false
v::optional(v::alpha())->validate(''); // true
v::optional(v::alpha())->validate(null); // true
// Negation rule
v::not(v::intVal())->validate(10); // false
バリデーターメソッド validate() check() assert() の違い
validate() は真偽値を返し、例外をスローしません
check() はバリデーション失敗時に例外をスローし、$exception->getMessage() で最初の失敗理由を取得します
assert() はバリデーション失敗時に例外をスローし、$exception->getFullMessage() で全ての失敗理由を取得します
よく使うバリデーションルール
Alnum() 英数字のみ
Alpha() 英字のみ
ArrayType() 配列型
Between(mixed $minimum, mixed $maximum) 入力が2つの値の間であることをバリデーション
BoolType() 真偽型のバリデーション
Contains(mixed $expectedValue) 入力が特定の値を含むことをバリデーション
ContainsAny(array $needles) 入力が定義された値の少なくとも1つを含むことをバリデーション
Digit() 入力が数字のみを含むことをバリデーション
Domain() 有効なドメイン名のバリデーション
Email() 有効なメールアドレスのバリデーション
Extension(string $extension) ファイル拡張子のバリデーション
FloatType() 浮動小数点型のバリデーション
IntType() 整数型のバリデーション
Ip() IP アドレスのバリデーション
Json() JSON データのバリデーション
Length(int $min, int $max) 長さが範囲内であることをバリデーション
LessThan(mixed $compareTo) 長さが指定値より小さいことをバリデーション
Lowercase() 小文字のバリデーション
MacAddress() MAC アドレスのバリデーション
NotEmpty() 空でないことのバリデーション
NullType() null のバリデーション
Number() 数値のバリデーション
ObjectType() オブジェクト型のバリデーション
StringType() 文字列型のバリデーション
Url() URL のバリデーション
その他のバリデーションルールは https://respect-validation.readthedocs.io/en/2.0/list-of-rules/ を参照してください。