Other Validators
There are many validators available in composer that can be used directly, such as:
webman/validation (Recommended)
top-think/think-validate
respect/validation
Validator webman/validation
Based on illuminate/validation, it provides manual validation, annotation validation, parameter-level validation, and reusable rule sets.
Installation
composer require webman/validation
Basic Concepts
- Rule Set Reuse: Define reusable
rules,messages,attributes, andscenesby extendingsupport\validation\Validator, which can be reused in both manual and annotation validation. - Method-Level Annotation (Attribute) Validation: Use PHP 8 attribute
#[Validate]to bind validation to controller methods. - Parameter-Level Annotation (Attribute) Validation: Use PHP 8 attribute
#[Param]to bind validation to controller method parameters. - Exception Handling: Throws
support\validation\ValidationExceptionon validation failure; the exception class is configurable. - Database Validation: If database validation is involved, you need to install
composer require webman/database.
Manual Validation
Basic Usage
use support\validation\Validator;
$data = ['email' => 'user@example.com'];
Validator::make($data, [
'email' => 'required|email',
])->validate();
Note
validate()throwssupport\validation\ValidationExceptionwhen validation fails. If you prefer not to throw exceptions, use thefails()approach below to get error messages.
Custom messages and attributes
use support\validation\Validator;
$data = ['contact' => 'user@example.com'];
Validator::make(
$data,
['contact' => 'required|email'],
['contact.email' => 'Invalid email format'],
['contact' => 'Email']
)->validate();
Validate Without Exception (Get Error Messages)
If you prefer not to throw exceptions, use fails() to check and get error messages via errors() (returns 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...
}
Rule Set Reuse (Custom Validator)
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',
];
}
Manual Validation Reuse
use app\validation\UserValidator;
UserValidator::make($data)->validate();
Use scenes (Optional)
scenes is an optional feature; it only validates a subset of fields when you call 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;
// No scene specified -> validate all rules
UserValidator::make($data)->validate();
// Specify scene -> validate only fields in that scene
UserValidator::make($data)->withScene('create')->validate();
Annotation Validation (Method-Level)
Direct Rules
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']);
}
}
Reuse Rule Sets
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']);
}
}
Multiple Validation Overlays
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']);
}
}
Validation Data Source
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']);
}
}
Use the in parameter to specify the data source:
- query HTTP request query parameters, from
$request->get() - body HTTP request body, from
$request->post() - path HTTP request path parameters, from
$request->route->param()
in can be a string or array; when it is an array, values are merged in order with later values overriding earlier ones. When in is not passed, it defaults to ['query', 'body', 'path'].
Parameter-Level Validation (Param)
Basic Usage
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']);
}
}
Validation Data Source
Similarly, parameter-level validation also supports the in parameter to specify the source:
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 supports string or array
use support\validation\annotation\Param;
class MailController
{
public function send(
#[Param(rules: ['required', 'email'])] string $from
) {
return json(['code' => 0, 'msg' => 'ok']);
}
}
Custom messages / attribute
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']);
}
}
Rule Constant Reuse
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']);
}
}
Method-Level + Parameter-Level Combined
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']);
}
}
Automatic Rule Inference (Based on Parameter Signature)
When #[Validate] is used on a method, or any parameter of that method uses #[Param], this component automatically infers and completes basic validation rules from the method parameter signature, then merges them with existing rules before validation.
Example: #[Validate] equivalent expansion
1) Only enable #[Validate] without writing rules manually:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate]
public function create(string $content, int $uid)
{
}
}
Equivalent to:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'required|string',
'uid' => 'required|integer',
])]
public function create(string $content, int $uid)
{
}
}
2) Only partial rules written, rest completed by parameter signature:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'min:2',
])]
public function create(string $content, int $uid)
{
}
}
Equivalent to:
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) Default value / nullable type:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate]
public function create(string $content = 'default', ?int $uid = null)
{
}
}
Equivalent to:
use support\validation\annotation\Validate;
class DemoController
{
#[Validate(rules: [
'content' => 'string',
'uid' => 'integer|nullable',
])]
public function create(string $content = 'default', ?int $uid = null)
{
}
}
Exception Handling
Default Exception
Validation failure throws support\validation\ValidationException by default, which extends Webman\Exception\BusinessException and does not log errors.
Default response behavior is handled by BusinessException::render():
- Regular requests: returns string message, e.g.
token is required. - JSON requests: returns JSON response, e.g.
{"code": 422, "msg": "token is required.", "data":....}
Customize handling via custom exception
- Global config:
exceptioninconfig/plugin/webman/validation/app.php
Multilingual Support
The component includes built-in Chinese and English language packs and supports project overrides. Load order:
- Project language pack
resource/translations/{locale}/validation.php - Component built-in
vendor/webman/validation/resources/lang/{locale}/validation.php - Illuminate built-in English (fallback)
Note
Webman default language is configured inconfig/translation.php, or can be changed vialocale('en');.
Local Override Example
resource/translations/zh_CN/validation.php
return [
'email' => ':attribute is not a valid email format.',
];
Middleware Auto-Loading
After installation, the component auto-loads the validation middleware via config/plugin/webman/validation/middleware.php; no manual registration is needed.
Command-Line Generation
Use the make:validator command to generate validator classes (default output to app/validation directory).
Note
Requirescomposer require webman/console
Basic Usage
- Generate empty template
php webman make:validator UserValidator
- Overwrite existing file
php webman make:validator UserValidator --force
php webman make:validator UserValidator -f
Generate rules from table structure
- Specify table name to generate base rules (infers
$rulesfrom field type/nullable/length etc.; excludes ORM-related fields by default: laravel usescreated_at/updated_at/deleted_at, thinkorm usescreate_time/update_time/delete_time)
php webman make:validator UserValidator --table=wa_users
php webman make:validator UserValidator -t wa_users
- Specify database connection (multi-connection scenarios)
php webman make:validator UserValidator --table=wa_users --database=mysql
php webman make:validator UserValidator -t wa_users -d mysql
Scenes
- Generate CRUD scenes:
create/update/delete/detail
php webman make:validator UserValidator --table=wa_users --scenes=crud
php webman make:validator UserValidator -t wa_users -s crud
The
updatescene includes the primary key field (for locating records) plus other fields;delete/detailinclude only the primary key by default.
ORM selection (laravel (illuminate/database) vs think-orm)
- Auto-select (default): Uses whichever is installed/configured; when both exist, uses illuminate by default
- Force specify
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
Complete example
php webman make:validator UserValidator -t wa_users -d mysql -s crud -o laravel -f
Unit Tests
From the webman/validation root directory, run:
composer install
vendor\bin\phpunit -c phpunit.xml
Validation Rules Reference
Available Validation Rules
[!IMPORTANT]
- Webman Validation is based on
illuminate/validation; rule names match Laravel and there are no Webman-specific rules.- Middleware validates data from
$request->all()(GET+POST) merged with route parameters by default, excluding uploaded files; for file rules, merge$request->file()into the data yourself, or callValidator::makemanually.current_passworddepends on auth guard;exists/uniquedepend on database connection and query builder; these rules are unavailable when the corresponding components are not integrated.
The following lists all available validation rules and their purposes:
Boolean
String
Numeric
Array
Date
File
Database
Utility
accepted
The field must be "yes", "on", 1, "1", true, or "true". Commonly used for scenarios like verifying user agreement to terms of service.
accepted_if:anotherfield,value,...
When another field equals the specified value, the field must be "yes", "on", 1, "1", true, or "true". Commonly used for conditional agreement scenarios.
active_url
The field must have a valid A or AAAA record. This rule first uses parse_url to extract the URL hostname, then validates with dns_get_record.
after:date
The field must be a value after the given date. The date is passed to strtotime to convert to a valid DateTime:
use support\validation\Validator;
Validator::make($data, [
'start_date' => 'required|date|after:tomorrow',
])->validate();
You can also pass another field name for comparison:
Validator::make($data, [
'finish_date' => 'required|date|after:start_date',
])->validate();
You can use the fluent date rule builder:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->after(\Carbon\Carbon::today()->addDays(7)),
],
])->validate();
afterToday and todayOrAfter conveniently express "must be after today" or "must be today or later":
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->afterToday(),
],
])->validate();
after_or_equal:date
The field must be on or after the given date. See after for more details.
You can use the fluent date rule builder:
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 allows specifying "satisfy any one rule set". For example, the following rule means username must be either an email address or an alphanumeric/underscore/dash string of at least 6 characters:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'username' => [
'required',
Rule::anyOf([
['string', 'email'],
['string', 'alpha_dash', 'min:6'],
]),
],
])->validate();
alpha
The field must be Unicode letters (\p{L} and \p{M}).
To allow only ASCII (a-z, A-Z), add the ascii option:
Validator::make($data, [
'username' => 'alpha:ascii',
])->validate();
alpha_dash
The field may only contain Unicode letters and numbers (\p{L}, \p{M}, \p{N}), plus ASCII hyphen (-) and underscore (_).
To allow only ASCII (a-z, A-Z, 0-9), add the ascii option:
Validator::make($data, [
'username' => 'alpha_dash:ascii',
])->validate();
alpha_num
The field may only contain Unicode letters and numbers (\p{L}, \p{M}, \p{N}).
To allow only ASCII (a-z, A-Z, 0-9), add the ascii option:
Validator::make($data, [
'username' => 'alpha_num:ascii',
])->validate();
array
The field must be a PHP array.
When the array rule has extra parameters, the input array keys must be in the parameter list. In the example, the admin key is not in the allowed list, so it is invalid:
use support\validation\Validator;
$input = [
'user' => [
'name' => 'Taylor Otwell',
'username' => 'taylorotwell',
'admin' => true,
],
];
Validator::make($input, [
'user' => 'array:name,username',
])->validate();
It is recommended to explicitly define allowed array keys in real projects.
ascii
The field may only contain 7-bit ASCII characters.
bail
Stop validating further rules for the field when the first rule fails.
This rule only affects the current field. For "stop on first failure globally", use Illuminate's validator directly and call stopOnFirstFailure().
before:date
The field must be before the given date. The date is passed to strtotime to convert to a valid DateTime. Like after, you can pass another field name for comparison.
You can use the fluent date rule builder:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->before(\Carbon\Carbon::today()->subDays(7)),
],
])->validate();
beforeToday and todayOrBefore conveniently express "must be before today" or "must be today or earlier":
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->beforeToday(),
],
])->validate();
before_or_equal:date
The field must be on or before the given date. The date is passed to strtotime to convert to a valid DateTime. Like after, you can pass another field name for comparison.
You can use the fluent date rule builder:
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
The field size must be between min and max (inclusive). Evaluation for strings, numbers, arrays, and files is the same as size.
boolean
The field must be convertible to boolean. Acceptable inputs include true, false, 1, 0, "1", "0".
Use the strict parameter to allow only true or false:
Validator::make($data, [
'foo' => 'boolean:strict',
])->validate();
confirmed
The field must have a matching {field}_confirmation field. For example, when the field is password, password_confirmation is required.
You can also specify a custom confirmation field name, e.g. confirmed:repeat_username requires repeat_username to match the current field.
contains:foo,bar,...
The field must be an array and must contain all given parameter values. This rule is commonly used for array validation; you can use Rule::contains to construct it:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'roles' => [
'required',
'array',
Rule::contains(['admin', 'editor']),
],
])->validate();
doesnt_contain:foo,bar,...
The field must be an array and must not contain any of the given parameter values. You can use Rule::doesntContain to construct it:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'roles' => [
'required',
'array',
Rule::doesntContain(['admin', 'editor']),
],
])->validate();
current_password
The field must match the current authenticated user's password. You can specify the auth guard as the first parameter:
Validator::make($data, [
'password' => 'current_password:api',
])->validate();
[!WARNING]
This rule depends on the auth component and guard configuration; do not use when auth is not integrated.
date
The field must be a valid (non-relative) date recognizable by strtotime.
date_equals:date
The field must equal the given date. The date is passed to strtotime to convert to a valid DateTime.
date_format:format,...
The field must match one of the given formats. Use either date or date_format. This rule supports all PHP DateTime formats.
You can use the fluent date rule builder:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'start_date' => [
'required',
Rule::date()->format('Y-m-d'),
],
])->validate();
decimal:min,max
The field must be numeric with the required decimal places:
Validator::make($data, [
'price' => 'decimal:2',
])->validate();
Validator::make($data, [
'price' => 'decimal:2,4',
])->validate();
declined
The field must be "no", "off", 0, "0", false, or "false".
declined_if:anotherfield,value,...
When another field equals the specified value, the field must be "no", "off", 0, "0", false, or "false".
different:field
The field must be different from field.
digits:value
The field must be an integer with length value.
digits_between:min,max
The field must be an integer with length between min and max.
dimensions
The field must be an image and satisfy dimension constraints:
Validator::make($data, [
'avatar' => 'dimensions:min_width=100,min_height=200',
])->validate();
Available constraints: min_width, max_width, min_height, max_height, width, height, ratio.
ratio is the aspect ratio; it can be expressed as a fraction or float:
Validator::make($data, [
'avatar' => 'dimensions:ratio=3/2',
])->validate();
This rule has many parameters; it is recommended to use Rule::dimensions to construct it:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'avatar' => [
'required',
Rule::dimensions()
->maxWidth(1000)
->maxHeight(500)
->ratio(3 / 2),
],
])->validate();
distinct
When validating arrays, field values must not be duplicated:
Validator::make($data, [
'foo.*.id' => 'distinct',
])->validate();
Uses loose comparison by default. Add strict for strict comparison:
Validator::make($data, [
'foo.*.id' => 'distinct:strict',
])->validate();
Add ignore_case to ignore case differences:
Validator::make($data, [
'foo.*.id' => 'distinct:ignore_case',
])->validate();
doesnt_start_with:foo,bar,...
The field must not start with any of the specified values.
doesnt_end_with:foo,bar,...
The field must not end with any of the specified values.
The field must be a valid email address. This rule depends on egulias/email-validator, uses RFCValidation by default, and can use other validation methods:
Validator::make($data, [
'email' => 'email:rfc,dns',
])->validate();
Available validation methods:
You can use the fluent rule builder:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
'required',
Rule::email()
->rfcCompliant(strict: false)
->validateMxRecord()
->preventSpoofing(),
],
])->validate();
[!WARNING]
dnsandspoofrequire the PHPintlextension.
encoding:encoding_type
The field must match the specified character encoding. This rule uses mb_check_encoding to detect file or string encoding. Can be used with the file rule builder:
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,...
The field must end with one of the specified values.
enum
Enum is a class-based rule for validating that the field value is a valid enum value. Pass the enum class name when constructing. For primitive values, use Backed Enum:
use app\enums\ServerStatus;
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'status' => [Rule::enum(ServerStatus::class)],
])->validate();
Use only/except to restrict enum values:
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();
Use when for conditional restrictions:
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
The field will be excluded from data returned by validate/validated.
exclude_if:anotherfield,value
When anotherfield equals value, the field will be excluded from data returned by validate/validated.
For complex conditions, use 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
Unless anotherfield equals value, the field will be excluded from data returned by validate/validated. If value is null (e.g. exclude_unless:name,null), the field is only kept when the comparison field is null or absent.
exclude_with:anotherfield
When anotherfield exists, the field will be excluded from data returned by validate/validated.
exclude_without:anotherfield
When anotherfield does not exist, the field will be excluded from data returned by validate/validated.
exists:table,column
The field must exist in the specified database table.
Basic usage of Exists rule
Validator::make($data, [
'state' => 'exists:states',
])->validate();
When column is not specified, the field name is used by default. So this example validates whether the state column exists in the states table.
Specifying a custom column name
Append the column name after the table name:
Validator::make($data, [
'state' => 'exists:states,abbreviation',
])->validate();
To specify a database connection, prefix the table name with the connection name:
Validator::make($data, [
'email' => 'exists:connection.staff,email',
])->validate();
You can also pass a model class name; the framework will resolve the table name:
Validator::make($data, [
'user_id' => 'exists:app\model\User,id',
])->validate();
For custom query conditions, use the Rule builder:
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();
You can also specify the column name directly in Rule::exists:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'state' => [Rule::exists('states', 'abbreviation')],
])->validate();
To validate a set of values exist, combine with the array rule:
Validator::make($data, [
'states' => ['array', Rule::exists('states', 'abbreviation')],
])->validate();
When both array and exists are present, a single query validates all values.
extensions:foo,bar,...
Validates that the uploaded file extension is in the allowed list:
Validator::make($data, [
'photo' => ['required', 'extensions:jpg,png'],
])->validate();
[!WARNING]
Do not rely on extension alone for file type validation; use with mimes or mimetypes.
file
The field must be a successfully uploaded file.
filled
When the field exists, its value must not be empty.
gt:field
The field must be greater than the given field or value. Both fields must have the same type. Evaluation for strings, numbers, arrays, and files is the same as size.
gte:field
The field must be greater than or equal to the given field or value. Both fields must have the same type. Evaluation for strings, numbers, arrays, and files is the same as size.
hex_color
The field must be a valid hex color value.
image
The field must be an image (jpg, jpeg, png, bmp, gif, or webp).
[!WARNING]
SVG is not allowed by default due to XSS risk. To allow it, addallow_svg:image:allow_svg.
in:foo,bar,...
The field must be in the given value list. You can use Rule::in to construct:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'zones' => [
'required',
Rule::in(['first-zone', 'second-zone']),
],
])->validate();
When combined with the array rule, each value in the input array must be in the in list:
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.*
The field must exist in the value list of anotherfield.
in_array_keys:value.*
The field must be an array and must contain at least one of the given values as a key:
Validator::make($data, [
'config' => 'array|in_array_keys:timezone',
])->validate();
integer
The field must be an integer.
Use the strict parameter to require the field type to be integer; string integers will be invalid:
Validator::make($data, [
'age' => 'integer:strict',
])->validate();
[!WARNING]
This rule only validates whether it passes PHP'sFILTER_VALIDATE_INT; for strict numeric types, use with numeric.
ip
The field must be a valid IP address.
ipv4
The field must be a valid IPv4 address.
ipv6
The field must be a valid IPv6 address.
json
The field must be a valid JSON string.
lt:field
The field must be less than the given field. Both fields must have the same type. Evaluation for strings, numbers, arrays, and files is the same as size.
lte:field
The field must be less than or equal to the given field. Both fields must have the same type. Evaluation for strings, numbers, arrays, and files is the same as size.
lowercase
The field must be lowercase.
list
The field must be a list array. List array keys must be consecutive numbers from 0 to count($array) - 1.
mac_address
The field must be a valid MAC address.
max:value
The field must be less than or equal to value. Evaluation for strings, numbers, arrays, and files is the same as size.
max_digits:value
The field must be an integer with length not exceeding value.
mimetypes:text/plain,...
Validates that the file's MIME type is in the list:
Validator::make($data, [
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime',
])->validate();
MIME type is guessed by reading file content and may differ from the client-provided MIME.
mimes:foo,bar,...
Validates that the file's MIME type corresponds to the given extension:
Validator::make($data, [
'photo' => 'mimes:jpg,bmp,png',
])->validate();
Although the parameters are extensions, this rule reads file content to determine MIME. Extension-to-MIME mapping:
https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
MIME types and extensions
This rule does not validate that "file extension" matches "actual MIME". For example, mimes:png treats photo.txt with PNG content as valid. To validate extension, use extensions.
min:value
The field must be greater than or equal to value. Evaluation for strings, numbers, arrays, and files is the same as size.
min_digits:value
The field must be an integer with length not less than value.
multiple_of:value
The field must be a multiple of value.
missing
The field must not exist in the input data.
missing_if:anotherfield,value,...
When anotherfield equals any value, the field must not exist.
missing_unless:anotherfield,value
Unless anotherfield equals any value, the field must not exist.
missing_with:foo,bar,...
When any specified field exists, the field must not exist.
missing_with_all:foo,bar,...
When all specified fields exist, the field must not exist.
not_in:foo,bar,...
The field must not be in the given value list. You can use Rule::notIn to construct:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'toppings' => [
'required',
Rule::notIn(['sprinkles', 'cherries']),
],
])->validate();
not_regex:pattern
The field must not match the given regular expression.
This rule uses PHP preg_match. The regex must have delimiters, e.g. 'email' => 'not_regex:/^.+$/i'.
[!WARNING]
When usingregex/not_regex, if the regex contains|, use array form to avoid conflict with the|separator.
nullable
The field may be null.
numeric
The field must be numeric.
Use the strict parameter to allow only integer or float types; numeric strings will be invalid:
Validator::make($data, [
'amount' => 'numeric:strict',
])->validate();
present
The field must exist in the input data.
present_if:anotherfield,value,...
When anotherfield equals any value, the field must exist.
present_unless:anotherfield,value
Unless anotherfield equals any value, the field must exist.
present_with:foo,bar,...
When any specified field exists, the field must exist.
present_with_all:foo,bar,...
When all specified fields exist, the field must exist.
prohibited
The field must be missing or empty. "Empty" means:
prohibited_if:anotherfield,value,...
When anotherfield equals any value, the field must be missing or empty. "Empty" means:
For complex conditions, use 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,...
When anotherfield is "yes", "on", 1, "1", true, or "true", the field must be missing or empty.
prohibited_if_declined:anotherfield,...
When anotherfield is "no", "off", 0, "0", false, or "false", the field must be missing or empty.
prohibited_unless:anotherfield,value,...
Unless anotherfield equals any value, the field must be missing or empty. "Empty" means:
prohibits:anotherfield,...
When the field exists and is not empty, all fields in anotherfield must be missing or empty. "Empty" means:
regex:pattern
The field must match the given regular expression.
This rule uses PHP preg_match. The regex must have delimiters, e.g. 'email' => 'regex:/^.+@.+$/i'.
[!WARNING]
When usingregex/not_regex, if the regex contains|, use array form to avoid conflict with the|separator.
required
The field must exist and not be empty. "Empty" means:
required_if:anotherfield,value,...
When anotherfield equals any value, the field must exist and not be empty.
For complex conditions, use 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,...
When anotherfield is "yes", "on", 1, "1", true, or "true", the field must exist and not be empty.
required_if_declined:anotherfield,...
When anotherfield is "no", "off", 0, "0", false, or "false", the field must exist and not be empty.
required_unless:anotherfield,value,...
Unless anotherfield equals any value, the field must exist and not be empty. If value is null (e.g. required_unless:name,null), the field may be empty only when the comparison field is null or absent.
required_with:foo,bar,...
When any specified field exists and is not empty, the field must exist and not be empty.
required_with_all:foo,bar,...
When all specified fields exist and are not empty, the field must exist and not be empty.
required_without:foo,bar,...
When any specified field is empty or absent, the field must exist and not be empty.
required_without_all:foo,bar,...
When all specified fields are empty or absent, the field must exist and not be empty.
required_array_keys:foo,bar,...
The field must be an array and must contain at least the specified keys.
sometimes
Apply subsequent validation rules only when the field exists. Commonly used for "optional but must be valid when present" fields:
Validator::make($data, [
'nickname' => 'sometimes|string|max:20',
])->validate();
same:field
The field must be the same as field.
size:value
The field size must equal the given value. For strings: character count; for numbers: specified integer (use with numeric or integer); for arrays: element count; for files: size in KB. Example:
Validator::make($data, [
'title' => 'size:12',
'seats' => 'integer|size:10',
'tags' => 'array|size:5',
'image' => 'file|size:512',
])->validate();
starts_with:foo,bar,...
The field must start with one of the specified values.
string
The field must be a string. To allow null, use with nullable.
timezone
The field must be a valid timezone identifier (from DateTimeZone::listIdentifiers). You can pass parameters supported by that method:
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
The field must be unique in the specified table.
Specify custom table/column name:
You can specify the model class name directly:
Validator::make($data, [
'email' => 'unique:app\model\User,email_address',
])->validate();
You can specify the column name (defaults to field name when not specified):
Validator::make($data, [
'email' => 'unique:users,email_address',
])->validate();
Specify database connection:
Validator::make($data, [
'email' => 'unique:connection.users,email_address',
])->validate();
Ignore specified ID:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
'required',
Rule::unique('users')->ignore($user->id),
],
])->validate();
[!WARNING]
ignoreshould not receive user input; only use system-generated unique IDs (auto-increment ID or model UUID), otherwise SQL injection risk may exist.
You can also pass a model instance:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users')->ignore($user),
],
])->validate();
If the primary key is not id, specify the primary key name:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users')->ignore($user->id, 'user_id'),
],
])->validate();
By default uses the field name as the unique column; you can also specify the column name:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [
Rule::unique('users', 'email_address')->ignore($user->id),
],
])->validate();
Add extra conditions:
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();
Ignore soft-deleted records:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [Rule::unique('users')->withoutTrashed()],
])->validate();
If the soft delete column is not deleted_at:
use support\validation\Rule;
use support\validation\Validator;
Validator::make($data, [
'email' => [Rule::unique('users')->withoutTrashed('was_deleted_at')],
])->validate();
uppercase
The field must be uppercase.
url
The field must be a valid URL.
You can specify allowed protocols:
Validator::make($data, [
'url' => 'url:http,https',
'game' => 'url:minecraft,steam',
])->validate();
ulid
The field must be a valid ULID.
uuid
The field must be a valid RFC 9562 UUID (version 1, 3, 4, 5, 6, 7, or 8).
You can specify the version:
Validator::make($data, [
'uuid' => 'uuid:4',
])->validate();
Validator top-think/think-validate
Description
Official ThinkPHP validator
Project URL
https://github.com/top-think/think-validate
Installation
composer require topthink/think-validate
Quick Start
Create 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());
}
Note
webman does not support think-validate'sValidate::rule()method
Validator workerman/validation
Description
This project is a localized version of https://github.com/Respect/Validation
Project URL
https://github.com/walkor/validation
Installation
composer require workerman/validation
Quick Start
<?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) validates and collects data. If validation fails, it throws Respect\Validation\Exceptions\ValidationException; on success it returns the validated data (array).
If the business code does not catch the validation exception, the webman framework will catch it and return JSON (like {"code":500, "msg":"xxx"}) or a normal exception page based on HTTP headers. If the response format does not meet your needs, you can catch ValidationException and return custom data, as in the example below:
<?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]);
}
}
Validator Guide
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
Difference between Validator methods validate() check() assert()
validate() returns boolean, does not throw exception
check() throws exception on validation failure; get first failure reason via $exception->getMessage()
assert() throws exception on validation failure; get all failure reasons via $exception->getFullMessage()
Common Validation Rules
Alnum() Only letters and numbers
Alpha() Only letters
ArrayType() Array type
Between(mixed $minimum, mixed $maximum) Validates that input is between two values.
BoolType() Validates boolean type
Contains(mixed $expectedValue) Validates that input contains certain value
ContainsAny(array $needles) Validates that input contains at least one defined value
Digit() Validates that input contains only digits
Domain() Validates valid domain name
Email() Validates valid email address
Extension(string $extension) Validates file extension
FloatType() Validates float type
IntType() Validates integer type
Ip() Validates IP address
Json() Validates JSON data
Length(int $min, int $max) Validates length is within range
LessThan(mixed $compareTo) Validates length is less than given value
Lowercase() Validates lowercase
MacAddress() Validates MAC address
NotEmpty() Validates not empty
NullType() Validates null
Number() Validates number
ObjectType() Validates object type
StringType() Validates string type
Url() Validates URL
See https://respect-validation.readthedocs.io/en/2.0/list-of-rules/ for more validation rules.