Validation
Introduction
Laravel provides several different approaches to validate your application's incoming data. It is most common to use the validate
method available on all incoming HTTP requests. However, we will discuss other approaches to validation as well.
Laravel includes a wide variety of convenient validation rules that you may apply to data, even providing the ability to validate if values are unique in a given database table. We'll cover each of these validation rules in detail so that you are familiar with all of Laravel's validation features.
Validation Quickstart
To learn about Laravel's powerful validation features, let's look at a complete example of validating a form and displaying the error messages back to the user. By reading this high-level overview, you'll be able to gain a good general understanding of how to validate incoming request data using Laravel:
Defining the Routes
First, let's assume we have the following routes defined in our routes/web.php
file:
use App\Http\Controllers\PostController;
Route::get('/post/create', [PostController::class, 'create']);
Route::post('/post', [PostController::class, 'store']);
The GET
route will display a form for the user to create a new blog post, while the POST
route will store the new blog post in the database.
Creating the Controller
Next, let's take a look at a simple controller that handles incoming requests to these routes. We'll leave the store
method empty for now:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class PostController extends Controller
{
/**
* Show the form to create a new blog post.
*/
public function create(): View
{
return view('post.create');
}
/**
* Store a new blog post.
*/
public function store(Request $request): RedirectResponse
{
// Validate and store the blog post...
$post = /** ... */
return to_route('post.show', ['post' => $post->id]);
}
}
Writing the Validation Logic
Now we are ready to fill in our store
method with the logic to validate the new blog post. To do this, we will use the validate
method provided by the Illuminate\Http\Request
object. If the validation rules pass, your code will keep executing normally; however, if validation fails, an Illuminate\Validation\ValidationException
exception will be thrown and the proper error response will automatically be sent back to the user.
If validation fails during a traditional HTTP request, a redirect response to the previous URL will be generated. If the incoming request is an XHR request, a JSON response containing the validation error messages will be returned.
To get a better understanding of the validate
method, let's jump back into the store
method:
/**
* Store a new blog post.
*/
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// The blog post is valid...
return redirect('/posts');
}
As you can see, the validation rules are passed into the validate
method. Don't worry - all available validation rules are documented. Again, if the validation fails, the proper response will automatically be generated. If the validation passes, our controller will continue executing normally.
Alternatively, validation rules may be specified as arrays of rules instead of a single |
delimited string:
$validatedData = $request->validate([
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
In addition, you may use the validateWithBag
method to validate a request and store any error messages within a named error bag:
$validatedData = $request->validateWithBag('post', [
'title' => ['required', 'unique:posts', 'max:255'],
'body' => ['required'],
]);
Stopping on First Validation Failure
Sometimes you may wish to stop running validation rules on an attribute after the first validation failure. To do so, assign the bail
rule to the attribute:
$request->validate([
'title' => 'bail|required|unique:posts|max:255',
'body' => 'required',
]);
In this example, if the unique
rule on the title
attribute fails, the max
rule will not be checked. Rules will be validated in the order they are assigned.
A Note on Nested Attributes
If the incoming HTTP request contains "nested" field data, you may specify these fields in your validation rules using "dot" syntax:
$request->validate([
'title' => 'required|unique:posts|max:255',
'author.name' => 'required',
'author.description' => 'required',
]);
On the other hand, if your field name contains a literal period, you can explicitly prevent this from being interpreted as "dot" syntax by escaping the period with a backslash:
$request->validate([
'title' => 'required|unique:posts|max:255',
'v1\.0' => 'required',
]);