Validation
- Things worth noting
- Numbers and Currency
- Unique
- Conditional Validation
- Validate Nested Properties (TBD)
-
in
Things worth noting
By default, Laravel includes the TrimStrings
and ConvertEmptyStringsToNull
middleware in your
application's global middleware stack. Because of this, you will often need to mark your "optional"
request fields as nullable
if you do not want the validator to consider null
values as invalid.
Numbers and Currency
This regex pattern will match any string that starts with one or more digits and optionally ends with a dot followed by exactly two digits.
'price' => 'required|regex:/^\d+(\.\d{2})?$/',
-
^
: This asserts the start of a line. The pattern must match at the beginning of the line. -
\d+
: This matches one or more digits (0-9). -
(\.\d{2})?
: This is a group that matches a dot (.) followed by exactly two digits. The question mark (?) after the group makes this group optional, meaning it can appear once or not at all. -
$
: This asserts the end of a line. The pattern must match at the end of the line.
Phone Number
'phone_number' => 'required|string|regex:/^[0-9+\s]+$/i|min:10',
In this example, we're validating a phone number input called "phone_number" that must be required, a string, and match the regular expression pattern of "^[0-9+\s]+$", which allows only numbers, plus sign, and spaces. We're also setting a minimum length of 10 characters and a maximum length of 20 characters for the phone number.
Unique
unique:table,column,except,idColumn
Ignore a given ID or a specific record
'code' => 'required|min:3|unique:courses,code,' . $this->course->id,
'email' => 'required|string|email|max:255|unique:users,email,' . auth()->user()->id,
use Illuminate\Validation\Rule;
'code' => ['required', Rule::unique('courses')->ignore($this->course)],
Unique Based on Multiple Conditions
The following validation rule is checking for uniqueness of the route_prefix
value, but only if the is_category
field is true
. If is_category
is
false
, the validation rule does nothing.
If is_category
is true, the validation rule checks whether any other record
in the pages table has a route_prefix
value that matches the route_prefix
value of the record being edited ($this->editing->route_prefix
), and also
has is_category
set to true
. If such a record exists, the validation rule
will fail (because the route_prefix
value must be unique for all
is_category
records with the same value).
This 'always false' condition is because the unique rule requires a valid
WHERE clause to work, and in this case, when the is_category
field is
false
, there is no need to apply any condition to the query.
'route_prefix' => [
Rule::requiredIf($this->editing->is_category),
Rule::unique('pages', 'route_prefix')
->where(function ($query) {
if ($this->editing->is_category) {
return $query->where('route_prefix', $this->editing->route_prefix);
}
return $query->whereRaw('1=0'); // always false condition
})
->ignore($this->editing->id)
],
Conditional Validation
Exclude
exclude_if
and exclude_unless
'field' => 'exclude_if:anotherField,value|required',
'field' => 'exclude_unless:anotherField,value|required',
you can check multiple against values using comma separated values.
Required
required_with
and required_with_all
'password' => 'required|confirmed|min:6',
'password_confirmation' => 'required_with:password',
required_if
and required_unless
'field' => 'required_if:anotherField,value,anotherValue',
'field' => 'required_unless:anotherField,value,anotherValue',
Validate Nested Properties (TBD)
'blocks.*.title' => [
'exclude_if:blocks.*.type,apple,banana', 'required'
],
// check nested values using dot notation
'field' => 'required_if:nested.anotherField,value,anotherValue',
'field' => 'required_unless:nested.anotherField,value,anotherValue',
in
Is valid option for the in
rule to use the keys
method on a collection to get a comma separated list of keys.
'status' => 'required|in:active,inactive,pending',
// convert to comma separated list of keys
'status' => 'required|in:' . collect(Order::STATUSES)->keys()->implode(','),