Laravel: validate an integer field that needs to be greater than another

PhpLaravelLaravel 5

Php Problem Overview


I have two fields that are optional only if both aren't present:

$rules = [
  'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
  'end_page' => 'required_with:initial_page|integer|min:2|digits_between:1,5'
]; 

Now, end_page needs to be greater than initial_page. How include this filter?

Php Solutions


Solution 1 - Php

There is no built-in validation that would let you compare field values like that in Laravel, so you'll need to implement a custom validator, that will let you reuse validation where needed. Luckily, Laravel makes writing custom validator really easy.

Start with defining new validator in yor AppServiceProvider:

class AppServiceProvider extends ServiceProvider
{
  public function boot()
  {
    Validator::extend('greater_than_field', function($attribute, $value, $parameters, $validator) {
      $min_field = $parameters[0];
      $data = $validator->getData();
      $min_value = $data[$min_field];
      return $value > $min_value;
    });   

    Validator::replacer('greater_than_field', function($message, $attribute, $rule, $parameters) {
      return str_replace(':field', $parameters[0], $message);
    });
  }
}

Now you can use your brand new validation rule in your $rules:

$rules = [
  'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
  'end_page' => 'required_with:initial_page|integer|greater_than_field:initial_page|digits_between:1,5'
]; 

You'll find more info about creating custom validators here: http://laravel.com/docs/5.1/validation#custom-validation-rules. They are easy to define and can then be used everywhere you validate your data.

Solution 2 - Php

the question was asked in 2015 so most of the answers are also outdated now in 2019

i want to give answer which uses features provided by laravel team which is included in it's new version,

so as stated by @Sarpadoruk as of laravel 5.6 laravel added features in validation like gt,gte,lt and lte which means:

  • gt - greater than
  • gte - greater than equal to
  • lt - less than
  • lte - less than equal to

so using gt you can check that your end_page should be greater than your initial_page and your task becomes very easy now:

$rules = [
  'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
  'end_page' => 'required_with:initial_page|integer|gt:initial_page|digits_between:1,5'
]; 

Solution 3 - Php

For Laravel 5.4 it will be:

$rules = ['end_page'=>'min:'.(int)$request->initial_page]

Solution 4 - Php

As of Laravel 5.6 gt, gte, lt and lte rules are added.

Solution 5 - Php

I think you can try something like this,

$init_page = Input::get('initial_page');

$rules = [
    'initial_page' => 'required_with:end_page|integer|min:1|digits_between: 1,5',
    'end_page' => 'required_with:initial_page|integer|min:'. ($init_page+1) .'|digits_between:1,5'
]; 

Solution 6 - Php

Why not just define $min_number = $min + 1 number and use validator min:$min_number, example:

$min = intval($data['min_number']) + 1;

return ['max_number'  => 'required|numeric|min:'.$min];

And you can then return custom error message to explain the error to user.

Solution 7 - Php

use gt = grater than :value|field

use gte = grater than equal :value|field

use lt = less than :value|field

use lte = less than equal :value|field

in your case it's

gt:initial_page

and the result will be

$rules = array(
      'initial_page' => 'required_with:end_page|numeric|min:1|digits_between: 1,5',
      'end_page' => 'required_with:initial_page|numeric|gt:initial_page|min:2|digits_between:1,5'
      );

Solution 8 - Php

If you're maintaining a project on Laravel 5.2 then the following should backport the current gt rule for you:

class AppServiceProvider extends ServiceProvider
{
  public function boot()
  {
    Validator::extend('gt', function($attribute, $value, $parameters, $validator) {
      $min_field = $parameters[0];
      $data = $validator->getData();
      $min_value = $data[$min_field];
      return $value > $min_value;
    });   

    Validator::replacer('gt', function($message, $attribute, $rule, $parameters) {
      return sprintf('%s must be greater than %s', $attribute, $parameters[0]);
    });
  }
}

You can then use it as per the current documentation:

$rules = [
  'end_page' => 'gt:initial_page'
]; 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexandre ThebaldiView Question on Stackoverflow
Solution 1 - Phpjedrzej.kuryloView Answer on Stackoverflow
Solution 2 - PhpHaritsinh GohilView Answer on Stackoverflow
Solution 3 - PhpNagibabaView Answer on Stackoverflow
Solution 4 - PhpSarpdoruk TahmazView Answer on Stackoverflow
Solution 5 - PhpKalhan.ToressView Answer on Stackoverflow
Solution 6 - PhpMahmoud Ali KassemView Answer on Stackoverflow
Solution 7 - PhpHusam M EkhraweshView Answer on Stackoverflow
Solution 8 - PhpcoatesapView Answer on Stackoverflow