In Laravel, what validation rules do I need to check the number of characters in a number? [duplicate]
Asked Answered
M

4

10

I'm using rules in validation in Laravel, and am trying to check the number of characters in a number.

This is my attempt:

protected static $rules = [
    'zip_code' => 'required|size:5|integer'
];

Unfortunately that checks that the zip code is the number 5 and not that the zip code is 5 characters. Which rules do I need to set to check that the zip code is exactly 5 characters, regardless of the actual numbers?

Marinara answered 10/2, 2015 at 23:26 Comment(1)
ZIP codes aren't integers. Integers have no leading zeroes, but some ZIP codes do.Zelaya
U
19

A zip code is 5 digits long and may contain leading zeros (Northeast US). The Laravel "digits" check drops the leading zeros as a result you need to use a regex pattern:

protected static $rules = [
     'zip_code' => 'required|regex:/\b\d{5}\b/'
];

This will make sure the zip code is always 5 digits long. More details in the Laravel Docs

Unstained answered 10/2, 2015 at 23:39 Comment(3)
That's exactly what I was looking for! No idea how I missed that. Must have been staring at validation rules for too long. Thanks so much for your help! You the man!Marinara
Do you have any idea where in the code Laravel files these rules are located? I'm curious what php code they used to determine their true/false values that get returned.Marinara
Yep, they're in vendor/laravel/framework/src/Illuminate/Validation/Validator.php. The methods that do the validation begin with validate, so for the digits rule you'll find validateDigits.Unstained
B
3

As per Laravel 5.3 :

If you are validating against character field which contains a number and you wanna know if it max 5 or lesser digits then you can use:

protected static $rules = [
    'zip_code' => 'required|max:5|string'
];

If you are validating against integer field and you wanna know if it contains max 5 or lesser digits then use:

protected static $rules = [
    'zip_code' => 'required|max:99999|integer'
];

If you are validating against integer field and you wanna know if it contains exact 5 digits then you can use:

protected static $rules = [
    'zip_code' => 'required|digits:5|integer'
];

Although in last case, zipcodes with leading zeroes will be trimmed and that's why for zipcodes I recommend using preg_match for validation. Define a custom validation rule in your AppServiceProvider file under boot function. For reference see this:

https://laravel.com/docs/5.3/validation#custom-validation-rules

and you should use varchar(10)(string,10 in laravel) instead of integer for zipcodes because:

  1. You cannot define size of integer in MySQL but you can for varchar.

  2. Zip codes can be 10 characters long with extension(zip+4, ex: 12345-1234).

I hope it helps

Bosanquet answered 4/1, 2017 at 8:5 Comment(0)
P
1

The above regex of \b\d{5}\b uses word boundaries and would pass validation as long as there are 5 grouped digits anywhere in the input. This is probably not what most people want.

For example, if the user submits Hello 00000 World!, validation would pass and your controller would receive the string Hello 00000 World! which is most likely not what it would be expecting and it would cry.


Validate 5 Digits (Zip)

I would suggest using anchors since all we want is 5 digits and absolutely nothing else to pass validation and in to the controller.

Something like this is simple and would work for 5 digits (a zip code):

protected static $rules = [
    'zip_code' => 'required|regex:/^\d{5}$/'
];

Validate 5 Digits a dash, and 4 Digits (Zip + 4)

Or, if you want to validate Zip+4, ie. 12345-6789 formatted zip codes you could do something like this:

protected static $rules = [
    'zip_code' => 'required|regex:/^\d{5}-\d{4}$/'
];

That would let 12345-6789 through, but not 1234-56789 or 123456789, etc.

Then something like this to handle it:

$zip = explode('-', $request->input('zip_code'));

$zip[0] would have 12345, which is the zip.

$zip[1] would have 6789, which is the +4.


Validate Either (Zip or Zip + 4)

Or, let's say you want to accept and validate either zip or zip+4 depending on what the user submitted. You could do something like this:

protected static $rules = [
    'zip_code' => 'required|regex:/^\d{5}(?:-\d{4})?$/'
];

That would let 12345 and 12345-6789 but fail on anything else.

Then you could the same as above since explode will still work on both variants but build an array of either one or two values depending.

$zip = explode('-', $request->input('zip_code'));

if (count($zip) > 1) {
    // do some zip+4 stuff
} else {
    // just a zip, lets do zip stuff
}
Pinkster answered 18/6, 2021 at 17:26 Comment(0)
E
-3

You getting this wrong instead on size:5 try min:5|max:5

Endeavor answered 16/4, 2016 at 20:50 Comment(1)
Using min or max on any numerical field will require that field to be between the min and max. For example, if you set min:5 and max:5, the number can only be five. If you set min:3 and max:10, the number can only be 3 - 10. See laravel.com/docs/8.x/validation#rule-sizeMegalo

© 2022 - 2024 — McMap. All rights reserved.