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?
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:/bd{5}b/'
];
This will make sure the zip code is always 5 digits long. More details in the Laravel Docs
The above regex of bd{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
}
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:
-
You cannot define size of integer in MySQL but you can for varchar.
-
Zip codes can be 10 characters long with extension(zip+4, ex: 12345-1234).
I hope it helps