Override the validate method, you probably missed it because it's defined in a trait:
public function validate()
{
parent::validate();
// Do something
}
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I would like to write a function in my FormRequest object to perform some custom validation steps in Laravel 5, but I can't seem to find a function to override/implement to perform these steps. What is the best approach to do something like that?
Override the validate method, you probably missed it because it's defined in a trait:
public function validate()
{
parent::validate();
// Do something
}
danielboendergaard, Thanks for your response and pointing me toward the trait. Overriding the validate function seems like it forces you to re-implement the core handling of valid/invalid data. Looking through the trait I saw the getValidatorInstance() method and came up with this solution based on a post here (http://mattstauffer.co/blog/laravel-5.0-form-requests):
public function getValidatorInstance() {
$validator = parent::getValidatorInstance();
$validator->after(function() use ($validator) {
// Do check here
if(// Invalid condition)
$validator->errors ()->add('field', 'message');
});
return $validator;
}
Does this seem like a clean way to add the additional conditions or will overriding this method cause problems down the road?
i'm not sure, if it works with 5.0
Thanks @nschiffelbein, you just set me on the right path!
Not sure if this is exactly how I should be doing it but it does work
public function getValidatorInstance() {
$validator = parent::getValidatorInstance();
$validator->after(function() use ($validator) {
$input = $this->formatInput();
$start = $this->carbon->parse($input['start']);
$end = $this->carbon->parse($input['end']);
if($start > $end) {
$validator->errors()->add('start', 'Start date must be later than end date');
}
if($start->diffInMinutes($end) > 180){
$validator->errors()->add('end', 'The end time must be within three hours of the start');
}
});
return $validator;
}
or now you can do like this when you want to move validator method to custom class in request class
class TestRequest extends Request {
public function validator($factory)
{
$factory->resolver = function ($translator, $data, $rules, $messages)
{
new TestValidator($translator, $data, $rules, $messages);
}
return $factory->make($this->formatInput(), $this->container->call([$this, 'rules']), $this->messages());
}
}
To create a new rule just extend Validator, for example :
<?php namespace app\Services;
use Illuminate\Validation\Validator;
class Validation extends Validator {
public function validateTags($attribute, $value, $parameters)
{
return preg_match("/^[A-Za-z0-9-éèàù]{1,50}?(,[A-Za-z0-9-éèàù]{1,50})*$/", $value);
}
}
And declare it in service provider :
use App\Services\Validation;
public function boot()
{
Validator::resolver(function($translator, $data, $rules, $messages)
{
return new Validation($translator, $data, $rules, $messages);
});
}
Take note that the class you should be using in the boot() method of Validator, should be an instance of the Validator Facade and not Illuminate\Validation\Validator.
@nschiffelbein as @bestmomo said, you should use custom validation rules if you want to perform custom validations.
Can anybody explain me what is wrong with my code?
I created CustomValidation class
<?php namespace App\Services\Validation;
use Illuminate\Validation\Validator;
class CustomValidation extends Validator{
//added only for test
public function validateTest($attribute, $value, $parameters)
{
return false;
}
}
I created service provider class
<?php namespace App\Services\Validation;
use Illuminate\Support\ServiceProvider;
use App\Services\Validation\CustomValidation;
class ValidationServiceProvider extends ServiceProvider{
public function register(){}
public function boot()
{
$this->app->validator->resolver(function($translator, $data, $rules, $messages)
{
return new CustomValidation($translator, $data, $rules, $messages);
});
}
}
I registered my service provider in app.php.
I'm trying to use CustomValidation in Registrar.php
<?php namespace App\Services;
use App\User;
use Validator;
use Illuminate\Contracts\Auth\Registrar as RegistrarContract;
class Registrar implements RegistrarContract {
public function validator(array $data)
{
return Validator::make($data, [
'username' => 'test',
],
[
'username.test' => 'Test.',
]
);
}
}
But this not works for me, it never fires. I had tried add die in my validation class in function validateTest but it not fired. Can anybody tell me what is my problem.
Thanks.
OK. I found my bug. I had sent empty field on server and custom validation was not worked.
Hey guys, if you are actually creating custom required rules, make sure you overwrite the $implicitRules attribute and add in the array the name of your custom required rule.
Otherwise you will run into the same bug than @stonebitsrl , because Laravel won't fire the validation when field is empty unless the rule is specified into $implicitRules.
Example :
<?php
namespace App\Services;
use Illuminate\Validation\Validator;
class CustomValidator extends Validator {
/**
* The validation rules that imply the field is required.
*
* @var array
*/
protected $implicitRules = [
'Required', 'RequiredWith', 'RequiredWithAll', 'RequiredWithout',
'RequiredWithoutAll', 'RequiredIf', 'Accepted', 'CustomRequiredA',
'CustomRequiredB'
];
public function validateCustomRequiredA($attribute, $value) {
return true;
}
public function validateCustomRequiredB($attribute, $value) {
return true;
}
Or if you prefer you can also do it in the constructor, maybe a more reliable way. Don't forget to import Symfony\Component\Translation\TranslatorInterface at the top if you are going to use this method.
public function __construct(TranslatorInterface $translator, array $data, array $rules, array $messages = array(), array $customAttributes = array()) {
parent::__construct($translator, $data, $rules, $messages, $customAttributes);
array_push($this->implicitRules, "CustomRequiredA", "CustomRequiredB");
}
That confused me at first, so I hope it can help someone in the futur.
STEP 1 of 3: Configure App Service Provider
app/Providers/AppServiceProvider.php
This file should already exist. You'll notice all that has been added for this example is in the boot method and the use Validator;
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('strength', 'App\Http\CustomValidator@validateStrength');
}
public function register()
{
//
}
}
STEP 2 of 3: Create Custom Validator Class
app/Http/CustomValidator.php
You can put this where ever you want and namespace it accordingly. The method name of the rule should be prepended with 'validate'.
NOTE! This class CANNOT extend the Validator class and if you do it throws and error: 'Unresolvable dependency resolving [Parameter #1...'
<?php
namespace App\Http;
class CustomValidator {
public function validateStrength($attribute, $value, $parameters, $validator)
{
if( preg_match('/(?=^.{8,}$)(?=.*\d)(?=.*[!@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/', $value) )
return true;
return false;
}
}
STEP 3 of 3: Edit Language File
resources/lang/en/validation.php
This file is basically a return statement with all of the default error messages. Here is an example of where your message will go as 'custom' is mentions a few places in the file and may be confusing to some. Of course you can place it anywhere as long as it's in the correct depth.
/*
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'strength' => 'The password :attribute is too weak and must contain one or more uppercase, lowercase, numeric, and special character (!@#$%^&*).',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
At this point you can use this validation rule. For example in a request...
public function rules()
{
return [
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:8|strength|confirmed',
];
}
@godigitalweb I must be close to the solution, but not there yet, as I get this message :
BadMethodCallException in Validator.php line 2678: Method [validateScheduleConflicts] does not exist.
I use laravel 5.1 , I asked about this here, but to no avail.
I did the modifications your post suggest, and I still get the error.
The given example by @godigitalweb fails with BadMethodCallException in Validator.php line 3394: Method [validateStrength] das not exists on Laravel 5.3
@godigitalweb it would be nice if you could help us with this... i also get an error BadMethodCallException. Can you test it and verify it with Laravel 5.3?
Hi,
I'm using Laravel 5.4.11 and the example works fine. For a reference here are the changes I made:
a) app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Validator::extend('strength', 'App\Validator\CustomValidator@validateStrength');
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
b) app/Validators/CustomValidator.php (New Directory)
<?php
namespace App\Validator;
class CustomValidator {
public function validateStrength($attribute, $value, $parameters, $validator)
{
if( preg_match('/(?=^.{8,}$)(?=.*\d)(?=.*[!@#$%^&*]+)(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/', $value) )
return true;
return false;
}
}
c) Error messages in resources/lang/en/validation
'strength' => 'The password :attribute is too weak and must contain one or more uppercase, lowercase, numeric, and special character (!@#$%^&*).',
'custom' => [
'attribute-name' => [
'rule-name' => 'custom-message',
],
],
d) Usage in the Request: app/Http/Requests/UserCreateFormRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserCreateFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'email'=> 'required',
'role'=> 'required',
'password'=>'alpha_num|min:6|strength|confirmed',
'password_confirmation'=>'alpha_num|min:6',
'company'=>'required|min:3',
'street'=>'required|min:3',
'zipcode'=>'required|numeric|min:5',
'location'=>'required|min:3',
];
}
}
!!!! An important moment. The rule name must consist strictly of lowercase letters. Without special characters and not CamelCase, lowerCamelCase!!!!
This work: 'strenght', 'super_strenght'.
This does not work: 'superStrenght', 'super-strenght'.
Laravel 5.4.32
Please or to participate in this conversation.