2148 lines
56 KiB
Markdown
2148 lines
56 KiB
Markdown
English | [中文](./README.zh-CN.md)
|
||
|
||
# Webman Validation
|
||
|
||
Webman's validation component, based on `illuminate/validation`, provides manual validation, annotation-based validation, parameter-level validation, and reusable rule sets.
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
composer require webman/validation
|
||
```
|
||
|
||
## Basic Concepts
|
||
|
||
- **Rule Set Reuse**: Define reusable `rules`, `messages`, `attributes`, and `scenes` by extending `support\validation\Validator`, which can be reused in manual and annotation validation.
|
||
- **Annotation (Attribute) Validation - Method-Level**: Use the PHP 8 attribute `#[Validate]` to bind validation to controller methods.
|
||
- **Annotation (Attribute) Validation - Parameter-Level**: Use the PHP 8 attribute `#[Param]` to bind validation to controller method parameters.
|
||
- **Exception Handling**: Throws `support\validation\ValidationException` on validation failure; the exception class is configurable via config.
|
||
- **Database Validation**: If database validation is involved, you need to install `composer require webman/database`.
|
||
|
||
## Manual Validation
|
||
|
||
### Basic Usage
|
||
|
||
```php
|
||
use support\validation\Validator;
|
||
|
||
$data = ['email' => 'user@example.com'];
|
||
|
||
Validator::make($data, [
|
||
'email' => 'required|email',
|
||
])->validate();
|
||
```
|
||
|
||
> **Note**
|
||
> `validate()` will throw `support\validation\ValidationException` if validation fails. If you prefer not to throw exceptions, use `fails()` as shown below.
|
||
|
||
### Custom Messages and Attributes
|
||
|
||
```php
|
||
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 don't want exceptions, use `fails()` and read errors from the `MessageBag`:
|
||
|
||
```php
|
||
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)
|
||
|
||
```php
|
||
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
|
||
|
||
```php
|
||
use app\validation\UserValidator;
|
||
|
||
UserValidator::make($data)->validate();
|
||
```
|
||
|
||
### Use Scenes (Optional)
|
||
|
||
Scenes are optional. They are only used when you call `withScene(...)` to validate a subset of fields.
|
||
|
||
```php
|
||
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'],
|
||
];
|
||
}
|
||
```
|
||
|
||
```php
|
||
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
|
||
|
||
```php
|
||
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']);
|
||
}
|
||
}
|
||
```
|
||
|
||
### Reusing Rule Sets
|
||
|
||
```php
|
||
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
|
||
|
||
```php
|
||
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
|
||
|
||
```php
|
||
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 `in` to specify where validation data comes from:
|
||
|
||
* **query** – HTTP query parameters from `$request->get()`
|
||
* **body** – HTTP body from `$request->post()`
|
||
* **path** – Path/route parameters from `$request->route->param()`
|
||
|
||
`in` can be a string or array; when it's an array, values are merged in order and later sources override earlier ones. When `in` is omitted, it defaults to the equivalent of `['query', 'body', 'path']`.
|
||
|
||
## Parameter-Level Validation (Param)
|
||
|
||
### Basic Usage
|
||
|
||
```php
|
||
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
|
||
|
||
Parameter-level validation also supports the `in` parameter to specify data source:
|
||
|
||
```php
|
||
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 Support String or Array
|
||
|
||
```php
|
||
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
|
||
|
||
```php
|
||
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']);
|
||
}
|
||
}
|
||
```
|
||
|
||
### Reusing Rule Constants
|
||
|
||
```php
|
||
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 Mixing
|
||
|
||
```php
|
||
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 (Signature-Based)
|
||
|
||
When a method uses `#[Validate]`, or any parameter on that method uses `#[Param]`, this package will **infer and auto-complete basic validation rules from the PHP method signature**, then merge them with your existing rules and run validation.
|
||
|
||
### Examples: `#[Validate]` Equivalent Expansion
|
||
|
||
1) Enable `#[Validate]` without writing rules:
|
||
|
||
```php
|
||
use support\validation\annotation\Validate;
|
||
|
||
class DemoController
|
||
{
|
||
#[Validate]
|
||
public function create(string $content, int $uid)
|
||
{
|
||
}
|
||
}
|
||
```
|
||
|
||
Equivalent to:
|
||
|
||
```php
|
||
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 provided, the rest is inferred:
|
||
|
||
```php
|
||
use support\validation\annotation\Validate;
|
||
|
||
class DemoController
|
||
{
|
||
#[Validate(rules: [
|
||
'content' => 'min:2',
|
||
])]
|
||
public function create(string $content, int $uid)
|
||
{
|
||
}
|
||
}
|
||
```
|
||
|
||
Equivalent to:
|
||
|
||
```php
|
||
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 values / nullable types:
|
||
|
||
```php
|
||
use support\validation\annotation\Validate;
|
||
|
||
class DemoController
|
||
{
|
||
#[Validate]
|
||
public function create(string $content = 'default', ?int $uid = null)
|
||
{
|
||
}
|
||
}
|
||
```
|
||
|
||
Equivalent to:
|
||
|
||
```php
|
||
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`, which inherits from `Webman\Exception\BusinessException` and does not log errors.
|
||
|
||
Default response behavior is handled by `BusinessException::render()`:
|
||
|
||
- Non-JSON requests: return a plain string message, e.g. `token is required.`
|
||
- JSON requests: return JSON response, e.g. `{"code": 422, "msg": "token is required.", "data":....}`
|
||
|
||
### Customize with a custom exception
|
||
|
||
- Global config: `exception` in `config/plugin/webman/validation/app.php`
|
||
|
||
## Multi-Language Support
|
||
|
||
The component includes built-in Chinese and English language packs and supports project overrides. Loading order:
|
||
|
||
1. Project language pack `resource/translations/{locale}/validation.php`
|
||
2. Component built-in `vendor/webman/validation/resources/lang/{locale}/validation.php`
|
||
3. Illuminate built-in English (fallback)
|
||
|
||
> **Note**
|
||
> The default language of webman is configured in `config/translation.php`, and it can also be changed using the function `locale('en');`.
|
||
|
||
### Local Override Example
|
||
|
||
`resource/translations/en/validation.php`
|
||
|
||
```php
|
||
return [
|
||
'email' => 'The :attribute is not a valid email format.',
|
||
];
|
||
```
|
||
|
||
## Middleware Auto-Loading
|
||
|
||
After installation, the component automatically loads the validation middleware via `config/plugin/webman/validation/middleware.php`, no manual registration required.
|
||
|
||
## CLI Generator
|
||
|
||
Use `make:validator` to generate a validator class (generated under `app/validation` by default).
|
||
|
||
> **Tip**
|
||
> You need to install `composer require webman/console`
|
||
|
||
### Basic
|
||
|
||
- **Generate an empty template**
|
||
|
||
```bash
|
||
php webman make:validator UserValidator
|
||
```
|
||
|
||
- **Overwrite if the file already exists**
|
||
|
||
```bash
|
||
php webman make:validator UserValidator --force
|
||
php webman make:validator UserValidator -f
|
||
```
|
||
|
||
### Generate rules from a table
|
||
|
||
- **Generate rules from a table schema** (infers `$rules` from column type/nullability/length; default excluded columns depend on ORM: laravel uses `created_at/updated_at/deleted_at`, thinkorm uses `create_time/update_time/delete_time`)
|
||
|
||
```bash
|
||
php webman make:validator UserValidator --table=wa_users
|
||
php webman make:validator UserValidator -t wa_users
|
||
```
|
||
|
||
- **Select a database connection** (multi-connection)
|
||
|
||
```bash
|
||
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`
|
||
|
||
```bash
|
||
php webman make:validator UserValidator --table=wa_users --scenes=crud
|
||
php webman make:validator UserValidator -t wa_users -s crud
|
||
```
|
||
|
||
> The `update` scene includes the primary key (to locate the record) plus the other fields; `delete/detail` include only primary key fields by default.
|
||
|
||
### ORM selection (laravel(illuminate/database) vs think-orm)
|
||
|
||
- **Auto (default)**: uses the available ORM; if both exist, defaults to illuminate
|
||
- **Force**
|
||
|
||
```bash
|
||
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
|
||
```
|
||
|
||
### Example
|
||
|
||
```bash
|
||
php webman make:validator UserValidator -t wa_users -d mysql -s crud -o laravel -f
|
||
```
|
||
|
||
|
||
## Unit Testing
|
||
|
||
Enter the `webman/validation` root directory and execute:
|
||
|
||
```bash
|
||
composer install
|
||
vendor\bin\phpunit -c phpunit.xml
|
||
```
|
||
|
||
## All Validation Rules Reference
|
||
<a name="available-validation-rules"></a>
|
||
## Available Validation Rules
|
||
|
||
> [!IMPORTANT]
|
||
> - Webman Validation is based on `illuminate/validation`, with rule names consistent with Laravel, and the rules themselves have no Webman-specific modifications.
|
||
> - The middleware validates data from `$request->all()` (GET+POST) by default and merges route parameters, excluding uploaded files; for file-related rules, manually merge `$request->file()` into the data or call `Validator::make` manually.
|
||
> - `current_password` depends on authentication guards, `exists`/`unique` depend on database connections and query builders, and these rules are unavailable without integrating the corresponding components.
|
||
|
||
The following lists all available validation rules and their functions:
|
||
|
||
<style>
|
||
.collection-method-list > p {
|
||
columns: 10.8em 3; -moz-columns: 10.8em 3; -webkit-columns: 10.8em 3;
|
||
}
|
||
|
||
.collection-method-list a {
|
||
display: block;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
</style>
|
||
|
||
#### Boolean Values
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Accepted](#rule-accepted)
|
||
[Accepted If](#rule-accepted-if)
|
||
[Boolean](#rule-boolean)
|
||
[Declined](#rule-declined)
|
||
[Declined If](#rule-declined-if)
|
||
|
||
</div>
|
||
|
||
#### Strings
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Active URL](#rule-active-url)
|
||
[Alpha](#rule-alpha)
|
||
[Alpha Dash](#rule-alpha-dash)
|
||
[Alpha Numeric](#rule-alpha-num)
|
||
[Ascii](#rule-ascii)
|
||
[Confirmed](#rule-confirmed)
|
||
[Current Password](#rule-current-password)
|
||
[Different](#rule-different)
|
||
[Doesnt Start With](#rule-doesnt-start-with)
|
||
[Doesnt End With](#rule-doesnt-end-with)
|
||
[Email](#rule-email)
|
||
[Ends With](#rule-ends-with)
|
||
[Enum](#rule-enum)
|
||
[Hex Color](#rule-hex-color)
|
||
[In](#rule-in)
|
||
[IP Address](#rule-ip)
|
||
[IPv4](#rule-ipv4)
|
||
[IPv6](#rule-ipv6)
|
||
[JSON](#rule-json)
|
||
[Lowercase](#rule-lowercase)
|
||
[MAC Address](#rule-mac)
|
||
[Max](#rule-max)
|
||
[Min](#rule-min)
|
||
[Not In](#rule-not-in)
|
||
[Regular Expression](#rule-regex)
|
||
[Not Regular Expression](#rule-not-regex)
|
||
[Same](#rule-same)
|
||
[Size](#rule-size)
|
||
[Starts With](#rule-starts-with)
|
||
[String](#rule-string)
|
||
[Uppercase](#rule-uppercase)
|
||
[URL](#rule-url)
|
||
[ULID](#rule-ulid)
|
||
[UUID](#rule-uuid)
|
||
|
||
</div>
|
||
|
||
#### Numbers
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Between](#rule-between)
|
||
[Decimal](#rule-decimal)
|
||
[Different](#rule-different)
|
||
[Digits](#rule-digits)
|
||
[Digits Between](#rule-digits-between)
|
||
[Greater Than](#rule-gt)
|
||
[Greater Than Or Equal](#rule-gte)
|
||
[Integer](#rule-integer)
|
||
[Less Than](#rule-lt)
|
||
[Less Than Or Equal](#rule-lte)
|
||
[Max](#rule-max)
|
||
[Max Digits](#rule-max-digits)
|
||
[Min](#rule-min)
|
||
[Min Digits](#rule-min-digits)
|
||
[Multiple Of](#rule-multiple-of)
|
||
[Numeric](#rule-numeric)
|
||
[Same](#rule-same)
|
||
[Size](#rule-size)
|
||
|
||
</div>
|
||
|
||
#### Arrays
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Array](#rule-array)
|
||
[Between](#rule-between)
|
||
[Contains](#rule-contains)
|
||
[Doesnt Contain](#rule-doesnt-contain)
|
||
[Distinct](#rule-distinct)
|
||
[In Array](#rule-in-array)
|
||
[In Array Keys](#rule-in-array-keys)
|
||
[List](#rule-list)
|
||
[Max](#rule-max)
|
||
[Min](#rule-min)
|
||
[Size](#rule-size)
|
||
|
||
</div>
|
||
|
||
#### Dates
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[After](#rule-after)
|
||
[After Or Equal](#rule-after-or-equal)
|
||
[Before](#rule-before)
|
||
[Before Or Equal](#rule-before-or-equal)
|
||
[Date](#rule-date)
|
||
[Date Equals](#rule-date-equals)
|
||
[Date Format](#rule-date-format)
|
||
[Different](#rule-different)
|
||
[Timezone](#rule-timezone)
|
||
|
||
</div>
|
||
|
||
#### Files
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Between](#rule-between)
|
||
[Dimensions](#rule-dimensions)
|
||
[Encoding](#rule-encoding)
|
||
[Extensions](#rule-extensions)
|
||
[File](#rule-file)
|
||
[Image](#rule-image)
|
||
[Max](#rule-max)
|
||
[MIME Types](#rule-mimetypes)
|
||
[MIME Type By File Extension](#rule-mimes)
|
||
[Size](#rule-size)
|
||
|
||
</div>
|
||
|
||
#### Database
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Exists](#rule-exists)
|
||
[Unique](#rule-unique)
|
||
|
||
</div>
|
||
|
||
#### Utilities
|
||
|
||
<div class="collection-method-list" markdown="1">
|
||
|
||
[Any Of](#rule-anyof)
|
||
[Bail](#rule-bail)
|
||
[Exclude](#rule-exclude)
|
||
[Exclude If](#rule-exclude-if)
|
||
[Exclude Unless](#rule-exclude-unless)
|
||
[Exclude With](#rule-exclude-with)
|
||
[Exclude Without](#rule-exclude-without)
|
||
[Filled](#rule-filled)
|
||
[Missing](#rule-missing)
|
||
[Missing If](#rule-missing-if)
|
||
[Missing Unless](#rule-missing-unless)
|
||
[Missing With](#rule-missing-with)
|
||
[Missing With All](#rule-missing-with-all)
|
||
[Nullable](#rule-nullable)
|
||
[Present](#rule-present)
|
||
[Present If](#rule-present-if)
|
||
[Present Unless](#rule-present-unless)
|
||
[Present With](#rule-present-with)
|
||
[Present With All](#rule-present-with-all)
|
||
[Prohibited](#rule-prohibited)
|
||
[Prohibited If](#rule-prohibited-if)
|
||
[Prohibited If Accepted](#rule-prohibited-if-accepted)
|
||
[Prohibited If Declined](#rule-prohibited-if-declined)
|
||
[Prohibited Unless](#rule-prohibited-unless)
|
||
[Prohibits](#rule-prohibits)
|
||
[Required](#rule-required)
|
||
[Required If](#rule-required-if)
|
||
[Required If Accepted](#rule-required-if-accepted)
|
||
[Required If Declined](#rule-required-if-declined)
|
||
[Required Unless](#rule-required-unless)
|
||
[Required With](#rule-required-with)
|
||
[Required With All](#rule-required-with-all)
|
||
[Required Without](#rule-required-without)
|
||
[Required Without All](#rule-required-without-all)
|
||
[Required Array Keys](#rule-required-array-keys)
|
||
[Sometimes](#validating-when-present)
|
||
|
||
</div>
|
||
|
||
<a name="rule-accepted"></a>
|
||
#### accepted
|
||
|
||
The field under validation must be `"yes"`, `"on"`, `1`, `"1"`, `true`, or `"true"`. This is commonly used for scenarios like confirming agreement to terms of service.
|
||
|
||
<a name="rule-accepted-if"></a>
|
||
#### accepted_if:anotherfield,value,...
|
||
|
||
The field under validation must be `"yes"`, `"on"`, `1`, `"1"`, `true`, or `"true"` when another field equals the specified value. This is useful for conditional agreement scenarios.
|
||
|
||
<a name="rule-active-url"></a>
|
||
#### active_url
|
||
|
||
The field under validation must have a valid A or AAAA record. The rule first extracts the hostname using `parse_url` and then validates it with `dns_get_record`.
|
||
|
||
<a name="rule-after"></a>
|
||
#### after:_date_
|
||
|
||
The field under validation must be a value after the given date. The date is converted to a valid `DateTime` using `strtotime`:
|
||
|
||
```php
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'start_date' => 'required|date|after:tomorrow',
|
||
])->validate();
|
||
```
|
||
|
||
You can also pass another field name for comparison:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'finish_date' => 'required|date|after:start_date',
|
||
])->validate();
|
||
```
|
||
|
||
You can use the fluent `date` rule builder:
|
||
|
||
```php
|
||
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` can conveniently express "must be after today" or "must be today or later":
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'start_date' => [
|
||
'required',
|
||
Rule::date()->afterToday(),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-after-or-equal"></a>
|
||
#### after_or_equal:_date_
|
||
|
||
The field under validation must be after or equal to the given date. For more details, see the [after](#rule-after) rule.
|
||
|
||
You can use the fluent `date` rule builder:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'start_date' => [
|
||
'required',
|
||
Rule::date()->afterOrEqual(\Carbon\Carbon::today()->addDays(7)),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-anyof"></a>
|
||
#### anyOf
|
||
|
||
`Rule::anyOf` allows specifying "pass if any one of the rule sets is satisfied". For example, the following rule means `username` is either an email address or an alphanumeric string with underscores/dashes of at least 6 characters:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'username' => [
|
||
'required',
|
||
Rule::anyOf([
|
||
['string', 'email'],
|
||
['string', 'alpha_dash', 'min:6'],
|
||
]),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-alpha"></a>
|
||
#### alpha
|
||
|
||
The field under validation must consist of Unicode letters ([\p{L}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AL%3A%5D&g=&i=) and [\p{M}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AM%3A%5D&g=&i=)).
|
||
|
||
To allow only ASCII (`a-z`, `A-Z`), add the `ascii` option:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'username' => 'alpha:ascii',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-alpha-dash"></a>
|
||
#### alpha_dash
|
||
|
||
The field under validation can only contain Unicode alphanumeric characters ([\p{L}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AL%3A%5D&g=&i=), [\p{M}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AM%3A%5D&g=&i=), [\p{N}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AN%3A%5D&g=&i=)), as well as ASCII dashes (`-`) and underscores (`_`).
|
||
|
||
To allow only ASCII (`a-z`, `A-Z`, `0-9`), add the `ascii` option:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'username' => 'alpha_dash:ascii',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-alpha-num"></a>
|
||
#### alpha_num
|
||
|
||
The field under validation can only contain Unicode alphanumeric characters ([\p{L}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AL%3A%5D&g=&i=), [\p{M}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AM%3A%5D&g=&i=), [\p{N}](https://util.unicode.org/UnicodeJsps/list-unicodeset.jsp?a=%5B%3AN%3A%5D&g=&i=)).
|
||
|
||
To allow only ASCII (`a-z`, `A-Z`, `0-9`), add the `ascii` option:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'username' => 'alpha_num:ascii',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-array"></a>
|
||
#### array
|
||
|
||
The field under validation must be a PHP `array`.
|
||
|
||
When the `array` rule includes additional parameters, the keys in the input array must be in the parameter list. In the example, the `admin` key is not in the allowed list, so it is invalid:
|
||
|
||
```php
|
||
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 specify the allowed keys for arrays in actual projects.
|
||
|
||
<a name="rule-ascii"></a>
|
||
#### ascii
|
||
|
||
The field under validation can only contain 7-bit ASCII characters.
|
||
|
||
<a name="rule-bail"></a>
|
||
#### bail
|
||
|
||
When the first validation rule for a field fails, stop validating the other rules for that field.
|
||
|
||
This rule only affects the current field. For "stop on first failure globally", use Illuminate's validator directly and call `stopOnFirstFailure()`.
|
||
|
||
<a name="rule-before"></a>
|
||
#### before:_date_
|
||
|
||
The field under validation must be before the given date. The date is converted to a valid `DateTime` using `strtotime`. Similar to the [after](#rule-after) rule, you can pass another field name for comparison.
|
||
|
||
You can use the fluent `date` rule builder:
|
||
|
||
```php
|
||
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` can conveniently express "must be before today" or "must be today or earlier":
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'start_date' => [
|
||
'required',
|
||
Rule::date()->beforeToday(),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-before-or-equal"></a>
|
||
#### before_or_equal:_date_
|
||
|
||
The field under validation must be before or equal to the given date. The date is converted to a valid `DateTime` using `strtotime`. Similar to the [after](#rule-after) rule, you can pass another field name for comparison.
|
||
|
||
You can use the fluent `date` rule builder:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'start_date' => [
|
||
'required',
|
||
Rule::date()->beforeOrEqual(\Carbon\Carbon::today()->subDays(7)),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-between"></a>
|
||
#### between:_min_,_max_
|
||
|
||
The field under validation must have a size between the given _min_ and _max_ (inclusive). Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-boolean"></a>
|
||
#### boolean
|
||
|
||
The field under validation must be convertible to a boolean value. Acceptable inputs include `true`, `false`, `1`, `0`, `"1"`, `"0"`.
|
||
|
||
You can use the `strict` parameter to allow only `true` or `false`:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'foo' => 'boolean:strict',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-confirmed"></a>
|
||
#### confirmed
|
||
|
||
The field under validation must have a matching field `{field}_confirmation`. For example, if the field is `password`, `password_confirmation` is required.
|
||
|
||
You can also specify a custom confirmation field name, such as `confirmed:repeat_username`, which requires `repeat_username` to match the current field.
|
||
|
||
<a name="rule-contains"></a>
|
||
#### contains:_foo_,_bar_,...
|
||
|
||
The field under validation must be an array and must contain all the given parameter values. This rule is often used for array validation and can be constructed using `Rule::contains`:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'roles' => [
|
||
'required',
|
||
'array',
|
||
Rule::contains(['admin', 'editor']),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-doesnt-contain"></a>
|
||
#### doesnt_contain:_foo_,_bar_,...
|
||
|
||
The field under validation must be an array and must not contain any of the given parameter values. You can use `Rule::doesntContain` to construct:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'roles' => [
|
||
'required',
|
||
'array',
|
||
Rule::doesntContain(['admin', 'editor']),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-current-password"></a>
|
||
#### current_password
|
||
|
||
The field under validation must match the current authenticated user's password. You can specify the authentication guard via the first parameter:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'password' => 'current_password:api',
|
||
])->validate();
|
||
```
|
||
|
||
> [!WARNING]
|
||
> This rule depends on the authentication component and guard configuration; do not use it without integrating authentication.
|
||
|
||
<a name="rule-date"></a>
|
||
#### date
|
||
|
||
The field under validation must be a valid (non-relative) date recognized by `strtotime`.
|
||
|
||
<a name="rule-date-equals"></a>
|
||
#### date_equals:_date_
|
||
|
||
The field under validation must equal the given date. The date is converted to a valid `DateTime` using `strtotime`.
|
||
|
||
<a name="rule-date-format"></a>
|
||
#### date_format:_format_,...
|
||
|
||
The field under validation must match one of the given formats. Use either `date` or `date_format`. This rule supports all formats of PHP [DateTime](https://www.php.net/manual/en/class.datetime.php).
|
||
|
||
You can use the fluent `date` rule builder:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'start_date' => [
|
||
'required',
|
||
Rule::date()->format('Y-m-d'),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-decimal"></a>
|
||
#### decimal:_min_,_max_
|
||
|
||
The field under validation must be a number with the specified number of decimal places:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'price' => 'decimal:2',
|
||
])->validate();
|
||
|
||
Validator::make($data, [
|
||
'price' => 'decimal:2,4',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-declined"></a>
|
||
#### declined
|
||
|
||
The field under validation must be `"no"`, `"off"`, `0`, `"0"`, `false`, or `"false"`.
|
||
|
||
<a name="rule-declined-if"></a>
|
||
#### declined_if:anotherfield,value,...
|
||
|
||
The field under validation must be `"no"`, `"off"`, `0`, `"0"`, `false`, or `"false"` when another field equals the specified value.
|
||
|
||
<a name="rule-different"></a>
|
||
#### different:_field_
|
||
|
||
The field under validation must be different from _field_.
|
||
|
||
<a name="rule-digits"></a>
|
||
#### digits:_value_
|
||
|
||
The field under validation must be an integer with a length of _value_.
|
||
|
||
<a name="rule-digits-between"></a>
|
||
#### digits_between:_min_,_max_
|
||
|
||
The field under validation must be an integer with a length between _min_ and _max_.
|
||
|
||
<a name="rule-dimensions"></a>
|
||
#### dimensions
|
||
|
||
The field under validation must be an image and satisfy the dimension constraints:
|
||
|
||
```php
|
||
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, which can be expressed as a fraction or float:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'avatar' => 'dimensions:ratio=3/2',
|
||
])->validate();
|
||
```
|
||
|
||
Due to the many parameters in this rule, it is recommended to use `Rule::dimensions` to construct:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'avatar' => [
|
||
'required',
|
||
Rule::dimensions()
|
||
->maxWidth(1000)
|
||
->maxHeight(500)
|
||
->ratio(3 / 2),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-distinct"></a>
|
||
#### distinct
|
||
|
||
When validating an array, the field values must not be duplicated:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'foo.*.id' => 'distinct',
|
||
])->validate();
|
||
```
|
||
|
||
By default, loose comparison is used. For strict comparison, add `strict`:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'foo.*.id' => 'distinct:strict',
|
||
])->validate();
|
||
```
|
||
|
||
You can add `ignore_case` to ignore case differences:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'foo.*.id' => 'distinct:ignore_case',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-doesnt-start-with"></a>
|
||
#### doesnt_start_with:_foo_,_bar_,...
|
||
|
||
The field under validation must not start with the specified values.
|
||
|
||
<a name="rule-doesnt-end-with"></a>
|
||
#### doesnt_end_with:_foo_,_bar_,...
|
||
|
||
The field under validation must not end with the specified values.
|
||
|
||
<a name="rule-email"></a>
|
||
#### email
|
||
|
||
The field under validation must be a valid email address. This rule relies on [egulias/email-validator](https://github.com/egulias/EmailValidator), defaulting to `RFCValidation`, but other validation methods can be specified:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'email' => 'email:rfc,dns',
|
||
])->validate();
|
||
```
|
||
|
||
Available validation methods:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- `rfc`: `RFCValidation` - Validates email according to RFC standards ([supported RFCs](https://github.com/egulias/EmailValidator?tab=readme-ov-file#supported-rfcs)).
|
||
- `strict`: `NoRFCWarningsValidation` - Fails on warnings during RFC validation (e.g., trailing dots or consecutive dots).
|
||
- `dns`: `DNSCheckValidation` - Checks if the domain has a valid MX record.
|
||
- `spoof`: `SpoofCheckValidation` - Prevents homoglyph or deceptive Unicode characters.
|
||
- `filter`: `FilterEmailValidation` - Validates using PHP `filter_var`.
|
||
- `filter_unicode`: `FilterEmailValidation::unicode()` - Unicode-allowed `filter_var` validation.
|
||
|
||
</div>
|
||
|
||
You can use the fluent rule builder:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [
|
||
'required',
|
||
Rule::email()
|
||
->rfcCompliant(strict: false)
|
||
->validateMxRecord()
|
||
->preventSpoofing(),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
> [!WARNING]
|
||
> `dns` and `spoof` require the PHP `intl` extension.
|
||
|
||
<a name="rule-encoding"></a>
|
||
#### encoding:*encoding_type*
|
||
|
||
The field under validation must match the specified character encoding. This rule uses `mb_check_encoding` to detect the encoding of files or strings. It can be used with the file rule builder:
|
||
|
||
```php
|
||
use Illuminate\Validation\Rules\File;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'attachment' => [
|
||
'required',
|
||
File::types(['csv'])->encoding('utf-8'),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-ends-with"></a>
|
||
#### ends_with:_foo_,_bar_,...
|
||
|
||
The field under validation must end with one of the specified values.
|
||
|
||
<a name="rule-enum"></a>
|
||
#### enum
|
||
|
||
`Enum` is a class-based rule used to validate if the field value is a valid enum value. Pass the enum class name during construction. For validating basic type values, use Backed Enum:
|
||
|
||
```php
|
||
use app\enums\ServerStatus;
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'status' => [Rule::enum(ServerStatus::class)],
|
||
])->validate();
|
||
```
|
||
|
||
You can use `only`/`except` to restrict enum values:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
You can use `when` for conditional restrictions:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
<a name="rule-exclude"></a>
|
||
#### exclude
|
||
|
||
The field under validation will be excluded from the data returned by `validate`/`validated`.
|
||
|
||
<a name="rule-exclude-if"></a>
|
||
#### exclude_if:_anotherfield_,_value_
|
||
|
||
The field under validation will be excluded from the data returned by `validate`/`validated` when _anotherfield_ equals _value_.
|
||
|
||
For complex conditions, use `Rule::excludeIf`:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
<a name="rule-exclude-unless"></a>
|
||
#### exclude_unless:_anotherfield_,_value_
|
||
|
||
The field under validation will be excluded from the data returned by `validate`/`validated` unless _anotherfield_ equals _value_. If _value_ is `null` (e.g., `exclude_unless:name,null`), the field is retained only if the comparison field is `null` or does not exist.
|
||
|
||
<a name="rule-exclude-with"></a>
|
||
#### exclude_with:_anotherfield_
|
||
|
||
The field under validation will be excluded from the data returned by `validate`/`validated` when _anotherfield_ exists.
|
||
|
||
<a name="rule-exclude-without"></a>
|
||
#### exclude_without:_anotherfield_
|
||
|
||
The field under validation will be excluded from the data returned by `validate`/`validated` when _anotherfield_ does not exist.
|
||
|
||
<a name="rule-exists"></a>
|
||
#### exists:_table_,_column_
|
||
|
||
The field under validation must exist in the specified database table.
|
||
|
||
<a name="basic-usage-of-exists-rule"></a>
|
||
#### Basic Usage of Exists Rule
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'state' => 'exists:states',
|
||
])->validate();
|
||
```
|
||
|
||
If `column` is not specified, the field name is used by default. Thus, this example validates if the `state` column exists in the `states` table.
|
||
|
||
<a name="specifying-a-custom-column-name"></a>
|
||
#### Specifying a Custom Column Name
|
||
|
||
You can append the column name after the table name:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'state' => 'exists:states,abbreviation',
|
||
])->validate();
|
||
```
|
||
|
||
To specify a database connection, prepend the connection name to the table:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'email' => 'exists:connection.staff,email',
|
||
])->validate();
|
||
```
|
||
|
||
You can also pass a model class name, and the framework will resolve the table name:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'user_id' => 'exists:app\model\User,id',
|
||
])->validate();
|
||
```
|
||
|
||
To customize query conditions, use the `Rule` rule builder:
|
||
|
||
```php
|
||
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`:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'state' => [Rule::exists('states', 'abbreviation')],
|
||
])->validate();
|
||
```
|
||
|
||
When validating if a group of values exists, combine with the `array` rule:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'states' => ['array', Rule::exists('states', 'abbreviation')],
|
||
])->validate();
|
||
```
|
||
|
||
When `array` and `exists` coexist, a single query is generated to validate all values.
|
||
|
||
<a name="rule-extensions"></a>
|
||
#### extensions:_foo_,_bar_,...
|
||
|
||
The uploaded file's extension must be in the allowed list:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'photo' => ['required', 'extensions:jpg,png'],
|
||
])->validate();
|
||
```
|
||
|
||
> [!WARNING]
|
||
> Do not rely solely on extension validation for file types; it is recommended to use it with [mimes](#rule-mimes) or [mimetypes](#rule-mimetypes).
|
||
|
||
<a name="rule-file"></a>
|
||
#### file
|
||
|
||
The field under validation must be a successfully uploaded file.
|
||
|
||
<a name="rule-filled"></a>
|
||
#### filled
|
||
|
||
When the field exists, its value must not be empty.
|
||
|
||
<a name="rule-gt"></a>
|
||
#### gt:_field_
|
||
|
||
The field under validation must be greater than the given _field_ or _value_. The two fields must be of the same type. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-gte"></a>
|
||
#### gte:_field_
|
||
|
||
The field under validation must be greater than or equal to the given _field_ or _value_. The two fields must be of the same type. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-hex-color"></a>
|
||
#### hex_color
|
||
|
||
The field under validation must be a valid [hexadecimal color value](https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color).
|
||
|
||
<a name="rule-image"></a>
|
||
#### image
|
||
|
||
The field under validation must be an image (jpg, jpeg, png, bmp, gif, or webp).
|
||
|
||
> [!WARNING]
|
||
> SVG is not allowed by default due to XSS risks. To allow it, add `allow_svg`: `image:allow_svg`.
|
||
|
||
<a name="rule-in"></a>
|
||
#### in:_foo_,_bar_,...
|
||
|
||
The field under validation must be in the given list of values. You can use `Rule::in` to construct:
|
||
|
||
```php
|
||
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, every value in the input array must be in the `in` list:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
$input = [
|
||
'airports' => ['NYC', 'LAS'],
|
||
];
|
||
|
||
Validator::make($input, [
|
||
'airports' => [
|
||
'required',
|
||
'array',
|
||
],
|
||
'airports.*' => Rule::in(['NYC', 'LIT']),
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-in-array"></a>
|
||
#### in_array:_anotherfield_.*
|
||
|
||
The field under validation must exist in the value list of _anotherfield_.
|
||
|
||
<a name="rule-in-array-keys"></a>
|
||
#### in_array_keys:_value_.*
|
||
|
||
The field under validation must be an array and must contain at least one of the given values as a key:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'config' => 'array|in_array_keys:timezone',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-integer"></a>
|
||
#### integer
|
||
|
||
The field under validation must be an integer.
|
||
|
||
You can use the `strict` parameter to require the field type to be integer; string representations of integers will be considered invalid:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'age' => 'integer:strict',
|
||
])->validate();
|
||
```
|
||
|
||
> [!WARNING]
|
||
> This rule only checks if it passes PHP's `FILTER_VALIDATE_INT`; to enforce numeric types, use it with [numeric](#rule-numeric).
|
||
|
||
<a name="rule-ip"></a>
|
||
#### ip
|
||
|
||
The field under validation must be a valid IP address.
|
||
|
||
<a name="rule-ipv4"></a>
|
||
#### ipv4
|
||
|
||
The field under validation must be a valid IPv4 address.
|
||
|
||
<a name="rule-ipv6"></a>
|
||
#### ipv6
|
||
|
||
The field under validation must be a valid IPv6 address.
|
||
|
||
<a name="rule-json"></a>
|
||
#### json
|
||
|
||
The field under validation must be a valid JSON string.
|
||
|
||
<a name="rule-lt"></a>
|
||
#### lt:_field_
|
||
|
||
The field under validation must be less than the given _field_. The two fields must be of the same type. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-lte"></a>
|
||
#### lte:_field_
|
||
|
||
The field under validation must be less than or equal to the given _field_. The two fields must be of the same type. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-lowercase"></a>
|
||
#### lowercase
|
||
|
||
The field under validation must be lowercase.
|
||
|
||
<a name="rule-list"></a>
|
||
#### list
|
||
|
||
The field under validation must be a list array. The keys in a list array must be consecutive numbers from 0 to `count($array) - 1`.
|
||
|
||
<a name="rule-mac"></a>
|
||
#### mac_address
|
||
|
||
The field under validation must be a valid MAC address.
|
||
|
||
<a name="rule-max"></a>
|
||
#### max:_value_
|
||
|
||
The field under validation must be less than or equal to _value_. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-max-digits"></a>
|
||
#### max_digits:_value_
|
||
|
||
The field under validation must be an integer with a length not exceeding _value_.
|
||
|
||
<a name="rule-mimetypes"></a>
|
||
#### mimetypes:_text/plain_,...
|
||
|
||
The file's MIME type must be in the list:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime',
|
||
])->validate();
|
||
```
|
||
|
||
The MIME type is guessed by reading the file content, which may differ from the client-provided MIME.
|
||
|
||
<a name="rule-mimes"></a>
|
||
#### mimes:_foo_,_bar_,...
|
||
|
||
The file's MIME type must correspond to the given extension:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'photo' => 'mimes:jpg,bmp,png',
|
||
])->validate();
|
||
```
|
||
|
||
Although the parameters are extensions, this rule reads the file content to determine the MIME. The extension-to-MIME mapping is from:
|
||
|
||
[https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types](https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types)
|
||
|
||
<a name="mime-types-and-extensions"></a>
|
||
#### MIME Types and Extensions
|
||
|
||
This rule does not validate if the "filename extension" matches the "actual MIME". For example, `mimes:png` will consider `photo.txt` with PNG content as valid. To validate extensions, use [extensions](#rule-extensions).
|
||
|
||
<a name="rule-min"></a>
|
||
#### min:_value_
|
||
|
||
The field under validation must be greater than or equal to _value_. Strings, numbers, arrays, and files are evaluated using the same rules as [size](#rule-size).
|
||
|
||
<a name="rule-min-digits"></a>
|
||
#### min_digits:_value_
|
||
|
||
The field under validation must be an integer with a length of at least _value_.
|
||
|
||
<a name="rule-multiple-of"></a>
|
||
#### multiple_of:_value_
|
||
|
||
The field under validation must be a multiple of _value_.
|
||
|
||
<a name="rule-missing"></a>
|
||
#### missing
|
||
|
||
The field under validation must not exist in the input data.
|
||
|
||
<a name="rule-missing-if"></a>
|
||
#### missing_if:_anotherfield_,_value_,...
|
||
|
||
The field under validation must not exist when _anotherfield_ equals any _value_.
|
||
|
||
<a name="rule-missing-unless"></a>
|
||
#### missing_unless:_anotherfield_,_value_
|
||
|
||
The field under validation must not exist unless _anotherfield_ equals any _value_.
|
||
|
||
<a name="rule-missing-with"></a>
|
||
#### missing_with:_foo_,_bar_,...
|
||
|
||
The field under validation must not exist when any of the specified fields exist.
|
||
|
||
<a name="rule-missing-with-all"></a>
|
||
#### missing_with_all:_foo_,_bar_,...
|
||
|
||
The field under validation must not exist when all specified fields exist.
|
||
|
||
<a name="rule-not-in"></a>
|
||
#### not_in:_foo_,_bar_,...
|
||
|
||
The field under validation must not be in the given list of values. You can use `Rule::notIn` to construct:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'toppings' => [
|
||
'required',
|
||
Rule::notIn(['sprinkles', 'cherries']),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-not-regex"></a>
|
||
#### not_regex:_pattern_
|
||
|
||
The field under validation must not match the given regular expression.
|
||
|
||
This rule uses PHP `preg_match`. The regex must include delimiters, e.g., `'email' => 'not_regex:/^.+$/i'`.
|
||
|
||
> [!WARNING]
|
||
> When using `regex` / `not_regex`, if the regex contains `|`, it is recommended to declare rules in array form to avoid conflicts with the `|` separator.
|
||
|
||
<a name="rule-nullable"></a>
|
||
#### nullable
|
||
|
||
The field under validation may be `null`.
|
||
|
||
<a name="rule-numeric"></a>
|
||
#### numeric
|
||
|
||
The field under validation must be [numeric](https://www.php.net/manual/en/function.is-numeric.php).
|
||
|
||
You can use the `strict` parameter to allow only integer or float types; numeric strings will be considered invalid:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'amount' => 'numeric:strict',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-present"></a>
|
||
#### present
|
||
|
||
The field under validation must exist in the input data.
|
||
|
||
<a name="rule-present-if"></a>
|
||
#### present_if:_anotherfield_,_value_,...
|
||
|
||
The field under validation must exist when _anotherfield_ equals any _value_.
|
||
|
||
<a name="rule-present-unless"></a>
|
||
#### present_unless:_anotherfield_,_value_
|
||
|
||
The field under validation must exist unless _anotherfield_ equals any _value_.
|
||
|
||
<a name="rule-present-with"></a>
|
||
#### present_with:_foo_,_bar_,...
|
||
|
||
The field under validation must exist when any of the specified fields exist.
|
||
|
||
<a name="rule-present-with-all"></a>
|
||
#### present_with_all:_foo_,_bar_,...
|
||
|
||
The field under validation must exist when all specified fields exist.
|
||
|
||
<a name="rule-prohibited"></a>
|
||
#### prohibited
|
||
|
||
The field under validation must be missing or empty. A field is "empty" if:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- The value is `null`.
|
||
- The value is an empty string.
|
||
- The value is an empty array or empty `Countable` object.
|
||
- It is an uploaded file with an empty path.
|
||
|
||
</div>
|
||
|
||
<a name="rule-prohibited-if"></a>
|
||
#### prohibited_if:_anotherfield_,_value_,...
|
||
|
||
The field under validation must be missing or empty when _anotherfield_ equals any _value_. A field is "empty" if:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- The value is `null`.
|
||
- The value is an empty string.
|
||
- The value is an empty array or empty `Countable` object.
|
||
- It is an uploaded file with an empty path.
|
||
|
||
</div>
|
||
|
||
For complex conditions, use `Rule::prohibitedIf`:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
<a name="rule-prohibited-if-accepted"></a>
|
||
#### prohibited_if_accepted:_anotherfield_,...
|
||
|
||
The field under validation must be missing or empty when _anotherfield_ is `"yes"`, `"on"`, `1`, `"1"`, `true`, or `"true"`.
|
||
|
||
<a name="rule-prohibited-if-declined"></a>
|
||
#### prohibited_if_declined:_anotherfield_,...
|
||
|
||
The field under validation must be missing or empty when _anotherfield_ is `"no"`, `"off"`, `0`, `"0"`, `false`, or `"false"`.
|
||
|
||
<a name="rule-prohibited-unless"></a>
|
||
#### prohibited_unless:_anotherfield_,_value_,...
|
||
|
||
The field under validation must be missing or empty unless _anotherfield_ equals any _value_. A field is "empty" if:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- The value is `null`.
|
||
- The value is an empty string.
|
||
- The value is an empty array or empty `Countable` object.
|
||
- It is an uploaded file with an empty path.
|
||
|
||
</div>
|
||
|
||
<a name="rule-prohibits"></a>
|
||
#### prohibits:_anotherfield_,...
|
||
|
||
When the field under validation exists and is not empty, all fields in _anotherfield_ must be missing or empty. A field is "empty" if:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- The value is `null`.
|
||
- The value is an empty string.
|
||
- The value is an empty array or empty `Countable` object.
|
||
- It is an uploaded file with an empty path.
|
||
|
||
</div>
|
||
|
||
<a name="rule-regex"></a>
|
||
#### regex:_pattern_
|
||
|
||
The field under validation must match the given regular expression.
|
||
|
||
This rule uses PHP `preg_match`. The regex must include delimiters, e.g., `'email' => 'regex:/^.+@.+$/i'`.
|
||
|
||
> [!WARNING]
|
||
> When using `regex` / `not_regex`, if the regex contains `|`, it is recommended to declare rules in array form to avoid conflicts with the `|` separator.
|
||
|
||
<a name="rule-required"></a>
|
||
#### required
|
||
|
||
The field under validation must exist and not be empty. A field is "empty" if:
|
||
|
||
<div class="content-list" markdown="1">
|
||
|
||
- The value is `null`.
|
||
- The value is an empty string.
|
||
- The value is an empty array or empty `Countable` object.
|
||
- It is an uploaded file with an empty path.
|
||
|
||
</div>
|
||
|
||
<a name="rule-required-if"></a>
|
||
#### required_if:_anotherfield_,_value_,...
|
||
|
||
The field under validation must exist and not be empty when _anotherfield_ equals any _value_.
|
||
|
||
For complex conditions, use `Rule::requiredIf`:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
<a name="rule-required-if-accepted"></a>
|
||
#### required_if_accepted:_anotherfield_,...
|
||
|
||
The field under validation must exist and not be empty when _anotherfield_ is `"yes"`, `"on"`, `1`, `"1"`, `true`, or `"true"`.
|
||
|
||
<a name="rule-required-if-declined"></a>
|
||
#### required_if_declined:_anotherfield_,...
|
||
|
||
The field under validation must exist and not be empty when _anotherfield_ is `"no"`, `"off"`, `0`, `"0"`, `false`, or `"false"`.
|
||
|
||
<a name="rule-required-unless"></a>
|
||
#### required_unless:_anotherfield_,_value_,...
|
||
|
||
The field under validation must exist and not be empty unless _anotherfield_ equals any _value_. If _value_ is `null` (e.g., `required_unless:name,null`), the field is allowed to be empty only if the comparison field is `null` or does not exist.
|
||
|
||
<a name="rule-required-with"></a>
|
||
#### required_with:_foo_,_bar_,...
|
||
|
||
The field under validation must exist and not be empty when any specified field exists and is not empty.
|
||
|
||
<a name="rule-required-with-all"></a>
|
||
#### required_with_all:_foo_,_bar_,...
|
||
|
||
The field under validation must exist and not be empty when all specified fields exist and are not empty.
|
||
|
||
<a name="rule-required-without"></a>
|
||
#### required_without:_foo_,_bar_,...
|
||
|
||
The field under validation must exist and not be empty when any specified field is empty or does not exist.
|
||
|
||
<a name="rule-required-without-all"></a>
|
||
#### required_without_all:_foo_,_bar_,...
|
||
|
||
The field under validation must exist and not be empty when all specified fields are empty or do not exist.
|
||
|
||
<a name="rule-required-array-keys"></a>
|
||
#### required_array_keys:_foo_,_bar_,...
|
||
|
||
The field under validation must be an array and must contain at least the specified keys.
|
||
|
||
<a name="validating-when-present"></a>
|
||
#### sometimes
|
||
|
||
Apply subsequent validation rules only when the field exists. Commonly used for fields that are "optional but must be valid if present":
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'nickname' => 'sometimes|string|max:20',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-same"></a>
|
||
#### same:_field_
|
||
|
||
The field under validation must be the same as _field_.
|
||
|
||
<a name="rule-size"></a>
|
||
#### size:_value_
|
||
|
||
The field under validation must have a size equal to the given _value_. For strings, it is the character count; for numbers, it is the specified integer (use with `numeric` or `integer`); for arrays, it is the element count; for files, it is the size in KB. Example:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'title' => 'size:12',
|
||
'seats' => 'integer|size:10',
|
||
'tags' => 'array|size:5',
|
||
'image' => 'file|size:512',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-starts-with"></a>
|
||
#### starts_with:_foo_,_bar_,...
|
||
|
||
The field under validation must start with one of the specified values.
|
||
|
||
<a name="rule-string"></a>
|
||
#### string
|
||
|
||
The field under validation must be a string. To allow `null`, use with `nullable`.
|
||
|
||
<a name="rule-timezone"></a>
|
||
#### timezone
|
||
|
||
The field under validation must be a valid timezone identifier (from `DateTimeZone::listIdentifiers`). Parameters supported by this method can be passed:
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
<a name="rule-unique"></a>
|
||
#### unique:_table_,_column_
|
||
|
||
The field under validation must be unique in the specified table.
|
||
|
||
**Specifying Custom Table/Column Names:**
|
||
|
||
You can directly specify the model class name:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'email' => 'unique:app\model\User,email_address',
|
||
])->validate();
|
||
```
|
||
|
||
You can specify the column name (defaults to the field name if not specified):
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'email' => 'unique:users,email_address',
|
||
])->validate();
|
||
```
|
||
|
||
**Specifying Database Connection:**
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'email' => 'unique:connection.users,email_address',
|
||
])->validate();
|
||
```
|
||
|
||
**Ignoring a Specific ID:**
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [
|
||
'required',
|
||
Rule::unique('users')->ignore($user->id),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
> [!WARNING]
|
||
> `ignore` should not receive user input; only use system-generated unique IDs (auto-increment IDs or model UUIDs), otherwise there may be SQL injection risks.
|
||
|
||
You can also pass a model instance:
|
||
|
||
```php
|
||
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:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [
|
||
Rule::unique('users')->ignore($user->id, 'user_id'),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
By default, the field name is used as the unique column, but you can specify the column name:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [
|
||
Rule::unique('users', 'email_address')->ignore($user->id),
|
||
],
|
||
])->validate();
|
||
```
|
||
|
||
**Adding Extra Conditions:**
|
||
|
||
```php
|
||
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();
|
||
```
|
||
|
||
**Ignoring Soft-Deleted Records:**
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [Rule::unique('users')->withoutTrashed()],
|
||
])->validate();
|
||
```
|
||
|
||
If the soft-delete column name is not `deleted_at`:
|
||
|
||
```php
|
||
use support\validation\Rule;
|
||
use support\validation\Validator;
|
||
|
||
Validator::make($data, [
|
||
'email' => [Rule::unique('users')->withoutTrashed('was_deleted_at')],
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-uppercase"></a>
|
||
#### uppercase
|
||
|
||
The field under validation must be uppercase.
|
||
|
||
<a name="rule-url"></a>
|
||
#### url
|
||
|
||
The field under validation must be a valid URL.
|
||
|
||
You can specify allowed protocols:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'url' => 'url:http,https',
|
||
'game' => 'url:minecraft,steam',
|
||
])->validate();
|
||
```
|
||
|
||
<a name="rule-ulid"></a>
|
||
#### ulid
|
||
|
||
The field under validation must be a valid [ULID](https://github.com/ulid/spec).
|
||
|
||
<a name="rule-uuid"></a>
|
||
#### uuid
|
||
|
||
The field under validation must be a valid RFC 9562 UUID (versions 1, 3, 4, 5, 6, 7, or 8).
|
||
|
||
You can specify the version:
|
||
|
||
```php
|
||
Validator::make($data, [
|
||
'uuid' => 'uuid:4',
|
||
])->validate();
|
||
``` |