Image validation

While validating uploaded images, you can specify the dimensions you require.

['photo' => 'dimensions:max_width=4096,max_height=4096']

Custom validation error messages

You can customize validation error messages per field, rule and language - just create a specific language file resources/lang/xx/validation.php with appropriate array structure.

'custom' => [ 'email' => [ 'required' => 'We need to know your e-mail address!', ],],

Validate dates with "now" or "yesterday" words

You can validate dates by rules before/after and passing various strings as a parameter, like: tomorrow, now, yesterday. Example: 'start_date' => 'after:now'. It's using strtotime() under the hood.

$rules = [ 'start_date' => 'after:tomorrow', 'end_date' => 'after:start_date'];

Validation Rule with Some Conditions

If your validation rules depend on some condition, you can modify the rules by adding withValidator() to your FormRequest class, and specify your custom logic there. Like, if you want to add validation rule only for some user role.

use Illuminate\Validation\Validator;class StoreBlogCategoryRequest extends FormRequest { public function withValidator(Validator $validator) { if (auth()->user()->is_admin) { $validator->addRules(['some_secret_password' => 'required']); } }}

Change Default Validation Messages

If you want to change default validation error message for specific field and specific validation rule, just add a messages() method into your FormRequest class.

class StoreUserRequest extends FormRequest{ public function rules() { return ['name' => 'required']; } public function messages() { return ['name.required' => 'User name should be real name']; }}

Prepare for Validation

If you want to modify some field before default Laravel validation, or, in other words, "prepare" that field, guess what - there's a method prepareForValidation() in FormRequest class:

protected function prepareForValidation(){ $this->merge([ 'slug' => Illuminate\Support\Str::slug($this->slug), ]);}

Stop on First Validation Error

By default, Laravel validation errors will be returned in a list, checking all validation rules. But if you want the process to stop after the first error, use validation rule called bail:

$request->validate([ 'title' => 'bail|required|unique:posts|max:255', 'body' => 'required',]);

If you need to stop validation on the first error in FormRequest class, you can set stopOnFirstFailure property to true:

protected $stopOnFirstFailure = true;

Throw 422 status code without using validate() or Form Request

If you don't use validate() or Form Request, but still need to throw errors with the same 422 status code and error structure, you can do it manually throw ValidationException::withMessages()

if (! $user || ! Hash::check($request->password, $user->password)) { throw ValidationException::withMessages([ 'email' => ['The provided credentials are incorrect.'], ]);}

Rules depending on some other conditions

If your rules are dynamic and depend on some other condition, you can create that array of rules on the fly

 public function store(Request $request) { $validationArray = [ 'title' => 'required', 'company' => 'required', 'logo' => 'file|max:2048', 'location' => 'required', 'apply_link' => 'required|url', 'content' => 'required', 'payment_method_id' => 'required' ]; if (!Auth::check()) { $validationArray = array_merge($validationArray, [ 'email' => 'required|email|unique:users', 'password' => 'required|confirmed|min:5', 'name' => 'required' ]); } // }

With Rule::when() we can conditionally apply validation rules

Thanks to Rule::when() we can conditionally apply validation rules in laravel.In this example we validate the value of the vote only if the user can actually vote the post.

use Illuminate\Validation\Rule;public function rules(){ return [ 'vote' => Rule::when($user->can('vote', $post), 'required|int|between:1,5'), ]}

Tip given by @cerbero90

Use this property in the request classes to stop the validation of the whole request attributes

Use this property in the request classes to stop the validation of the whole request attributes.

Hint DirectThis is different from Bail rule that stops the validation for just a single attribute if one of its rules doesn't validate.

/*** Indicated if the validator should stop * the entire validation once a single * rule failure has occurred. */protected $stopOnFirstFailure = true;

Tip given by @Sala7JR

Rule::unique doesn't take into the SoftDeletes Global Scope applied on the Model

Strange that Rule::unique doesn't take into the SoftDeletes Global Scope applied on the Model, by default.But withoutTrashed() method is available

Rule::unique('users', 'email')->withoutTrashed();

Tip given by @Zubairmohsin33

Validator::sometimes() method allows us to define when a validation rule should be applied

The laravel Validator::sometimes() method allows us to define when a validation rule should be applied, based on the input provided.The snippet shows how to prohibit the use of a coupon if the quantity of the purchased items is not enough.

$data = [ 'coupon' => 'PIZZA_PARTY', 'items' => [ [ 'id' => 1, 'quantity' => 2 ], [ 'id' => 2, 'quantity' => 2, ], ],];$validator = Validator::make($data, [ 'coupon' => 'exists:coupons,name', 'items' => 'required|array', 'items.*.id' => 'required|int', 'items.*.quantity' => 'required|int',]);$validator->sometimes('coupon', 'prohibited', function (Fluent $data) { return collect($data->items)->sum('quantity') < 5;});// throws a ValidationException as the quantity provided is not enough$validator->validate();

Tip given by @cerbero90

Array elements validation

If you want to validate elements of an array that you submited use dot notation in rules with '*'

// say you have this array// array in request 'user_info'$request->validated()->user_info = [ [ 'name' => 'Qasim', 'age' => 26, ], [ 'name' => 'Ahmed', 'age' => 23, ],];// Rule$rules = [ 'user_info.*.name' => ['required', 'alpha'], 'user_info.*.age' => ['required', 'numeric'],];

Tip given by HydroMoon

Password::defaults method

You can enforce specific rules when validating user-supplied passwords by using the Password::defaults method. It includes options for requiring letters, numbers, symbols, and more.

class AppServiceProvider{ public function boot(): void { Password::defaults(function () { return Password::min(12) ->letters() ->numbers() ->symbols() ->mixedCase() ->uncompromised(); }) }}request()->validate([ ['password' => ['required', Password::defaults()]]])

Tip given by @mattkingshott

Form Requests for validation redirection

when using Form Requests for validation, by default the validation error will redirect back to the previous page, but you can override it.Just define the property of $redirect or $redirectRoute.Link to docs

// The URI that users should be redirected to if validation fails./protected $redirect = '/dashboard';// The route that users should be redirected to if validation fails.protected $redirectRoute = 'dashboard';

Mac validation rule

New mac_address validation rule added in Laravel 8.77

$trans = $this->getIlluminateArrayTranslator();$validator = new Validator($trans, ['mac' => '01-23-45-67-89-ab'], ['mac' => 'mac_address']);$this->assertTrue($validator->passes());

Tip given by @Teacoders

Validate email with TLD domain required

By default, the email validation rule will accept an email without tld domain (ie: taylor@laravel, povilas@ldaily)

But if you want to make sure the email must have a tld domain (ie: [email protected], [email protected]), use email:filter rule.

[ 'email' => 'required|email', // before 'email' => 'required|email:filter', // after],

Tip given by @Chris1904

New array validation rule required_array_keys

Laravel 8.82 adds a required_array_keys validation rule. The rule checks that all of the specified keys exist in an array.

Valid data that would pass the validation:

$data = [ 'baz' => [ 'foo' => 'bar', 'fee' => 'faa', 'laa' => 'lee' ],];$rules = [ 'baz' => [ 'array', 'required_array_keys:foo,fee,laa', ],];$validator = Validator::make($data, $rules);$validator->passes(); // true

Invalid data that would fail the validation:

$data = [ 'baz' => [ 'foo' => 'bar', 'fee' => 'faa', ],];$rules = [ 'baz' => [ 'array', 'required_array_keys:foo,fee,laa', ],];$validator = Validator::make($data, $rules);$validator->passes(); // false

Tip given by @AshAllenDesign

Position placeholder in validation messages

In Laravel 9 you can use the :position placeholder in validation messages if you're working with arrays.

This will output: "Please provide an amount for price #2"

class CreateProductRequest extends FormRequest{ public function rules(): array { return [ 'title' => ['required', 'string']; 'description' => ['nullable', 'sometimes', 'string'], 'prices' => ['required', 'array'], 'prices.*.amount' => ['required', 'numeric'], 'prices.*.expired_at' => ['required', 'date'], ]; } public function messages(): array { 'prices.*.amount.required' => 'Please provide an amount for price #:position' }}

Tip given by @mmartin_joo

Exclude validation value

When you need to validate a field, but don't actually require it for anything e.g. 'accept terms and conditions', make use of the exclude rule. That way, the validated method won't return it...

class StoreRequest extends FormRequest{ public function rules(): array { return [ 'name' => 'required|string', 'email_address' => 'required|email', 'terms_and_conditions' => 'required|accepted|exclude', ]; }
class RegistrationController extends Controller{ public function store(StoreRequest $request) { $payload = $request->validated(); // only name and email $user = User::create($payload); Auth::login($user); return redirect()->route('dashboard'); }

Tip given by @mattkingshott

We use cookies to improve your experience and to help us understand how you use our site. By using this site, you accept our use of cookies. Cookie Infox