Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

cooperino's avatar

Can I pass a value of another field to custom validation rule?

I need to validate rule_2 based on the value of rule_1 value, so I need to pass the value of rule_1 to a custom rule I create for rule_2, is it possible? Because I know that using a custom rule is simply the rule name without parentheses:

'rule_2' => [new CustomRule] 

so how can I pass the value of rule_1 to this custom rule and conditionally set validation rules on it?

1 like
18 replies
Sinnbeck's avatar
'rule_2' => [new CustomRule($request->input('rule_1'))] 
cooperino's avatar

@Sinnbeck Thank you, didn't know it's allowed. Then this value will be available at the rule's constructor right?

Also, is it common? Or I should avoid this and find another solution?

cooperino's avatar

@Sinnbeck But then in the validation rules of the custom rule:

public function passes($attribute, $value)
{

is there any way to use the validation rules of Laravel? For example somehow for min max values have simple array:

['min: 3', 'max:10']

or I will have to use PHP:

if ($value > 3 && $value < 10) return true;
Sinnbeck's avatar

@cooperino Why not just add all validaiton rules?

'rule_2' => [new CustomRule($request->input('rule_1')), 'min: 3', 'max:10']
1 like
cooperino's avatar

@Sinnbeck because rule_1 can have three options, and the min/max for rule_2 is different based on rule_1 value, that's why I feel that something is wrong with what I'm doing

Sinnbeck's avatar

@cooperino Then it is a complete separate rule, and and I would personally not depend on other rules. Just use php to check. While you can make a manual validator, and use that, I personally prefer pure php for a simple check like that.

I have my own custom validation rules for data and timestamps, and all of these are handled directly using carbon, not the date validator.

1 like
cooperino's avatar

@Sinnbeck Oh, so you mean I should do completely different thing, and if I understand correctly it would be:

'multi_option' => ['required'],
'rule_2' => ['required_if: multi_option, value_1', 'min:3', 'max:10', 'regex: some_regex_1'],
'rule_3' => ['required_if: multi_option, value_2', 'min:2', 'max:8' ,'regex: some_regex_2'],
'rule_4' => ['required_if: multi_option, value_3', 'min:6', 'max:30', 'regex: some_regex_3'],

And I do not even need custom rule in this case

Sinnbeck's avatar

@cooperino I mean I would add a custom and have that check if it passes using simple php logic.

'rule_2' => [new CustomRule($request->input('rule_1'))]
1 like
cooperino's avatar

@Sinnbeck But that is the situation right now. With the new approach I wrote above, it does the same (I think - perhaps just without the custom messages which aren't necessary), unless those required_ifs will not behave as expected

Because as above, it will only validate the rule (required_if) based on the value of the multi select field)

Sinnbeck's avatar

@cooperino required_if just ensures that the rule_2 is required, if multi_option is equal to value_1

1 like
cooperino's avatar

@Sinnbeck But then it will have to continue with the other validation rules in that array and validate accordingly? so if rule_2 is required, and it contains more validation rules, then it will validate them as well?

And if user selected value_1 and the rule for value_1 is:

'rule_2' => 'rule_2' => ['required_if: multi_option, value_1', 'min:3', 'max:10', 'regex: some_regex_1'],

Then also check for the rest of the validation in that array (min, max, regex)?

Sinnbeck's avatar

@cooperino It will still validate them. It only either adds or remove the required validation rule.

You can use php to set up the array if you want

'rule_2' => array_merge(['required'], $request->multi_option === 'value1' ? ['min:3', 'max:10', 'regex: some_regex_1'] : []),

1 like
cooperino's avatar

@Sinnbeck Oh so it will validate them if they are present, but if not - it will not validate, which is exactly what I need. What you mean is, that if they existed in the request I would need to worry that it will still be validated.

But in my case, they user selects only one of the options, so the rest will not exist at all, thus not be validated. So in my case it will work?

Did I understand correctly?

Sinnbeck's avatar

@cooperino It only changes the required rule. So remove the required parameter and see if it then passes if its empty (If I understand you correctly it should)

1 like
cooperino's avatar

@Sinnbeck From some reason the following doesn't work at all (Not working, without any errors)

'multi_option_select' => ['required_unless:is_from_route_one,false', Rule::in(['value_1', 'value_2', 'value_3'])],
'rule_2' => ['required_if: multi_option_select, value_1', 'min:10','max:20'],

when I dd, these fields exist with a value

katayamahide's avatar

hi, here is my solution on Laravel8.

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Illuminate\Contracts\Validation\ValidatorAwareRule;

class MyCustomRule implements Rule, ValidatorAwareRule
{
    /**
     * validator instance
     *
     * @var \Illuminate\Validation\Validator
     */
    protected $validator;

    /**
     * field name
     *
     * @var string
     */
    protected $fieldName;

    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($fieldName)
    {
        // you can pass it when instanciating the class such as new MyCustomRule('rule_1')
        $this->fieldName = $fieldName;
    }

    /**
     * set validator instance
     *
     * @param  \Illuminate\Validation\Validator  $validator
     * @return $this
     */
    public function setValidator($validator)
    {
        $this->validator = $validator;

        return $this;
    }

    /**
     * determine if validation passes
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $fieldValue = $this->validator->getValue($this->fieldName);
        // continue your logic here
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        // your custom error message here
    }
}

On Laravel9 or Newer.

<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\DataAwareRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Validation\Validator;

class TotalHundred implements DataAwareRule, ValidationRule
{
    /**
     * All of the data under validation.
     *
     * @var array<string, mixed>
     */
    protected $data = [];

    /**
     * The validator instance.
     *
     * @var \Illuminate\Validation\Validator
     */
    protected $validator;

    /**
     * The field name passed to the rule.
     *
     * @var string
     */
    protected $fieldName;
    
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct($fieldName)
    {
        // you can pass it when instanciating the class such as new MyCustomRule('rule_1')
        $this->fieldName = $fieldName;
    }

    /**
     * Set the data under validation.
     *
     * @param  array<string, mixed>  $data
     */
    public function setData(array $data): static
    {
        $this->data = $data;

        return $this;
    }

    /**
     * Set the current validator.
     */
    public function setValidator(Validator $validator): static
    {
        $this->validator = $validator;
 
        return $this;
    }

    /**
     * Run the validation rule.
     *
     * @param  \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
     */
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $fieldValue = $this->data[$this->fieldName];
        // continue your logic here
    }
}

1 like

Please or to participate in this conversation.