Creating Form Requests
For more complex validation scenarios, you may wish to create a "form request". Form requests are custom request classes that contain validation logic. To create a form request class, use the make:request
Artisan CLI command:
php artisan make:request StoreBlogPost
The generated class will be placed in the app/Http/Requests
directory. If this directory does not exist, it will be created when you run the make:request
command. Let's add a few validation rules to the rules
method:
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
So, how are the validation rules evaluated? All you need to do is type-hint the request on your controller method. The incoming form request is validated before the controller method is called, meaning you do not need to clutter your controller with any validation logic:
/**
* Store the incoming blog post.
*
* @param StoreBlogPost $request
* @return Response
*/
public function store(StoreBlogPost $request)
{
// The incoming request is valid...
// Retrieve the validated input data...
$validated = $request->validated();
}
If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.
Adding After Hooks To Form Requests
If you would like to add an "after" hook to a form request, you may use the withValidator
method. This method receives the fully constructed validator, allowing you to call any of its methods before the validation rules are actually evaluated:
/**
* Configure the validator instance.
*
* @param \Illuminate\Validation\Validator $validator
* @return void
*/
public function withValidator($validator)
{
$validator->after(function ($validator) {
if ($this->somethingElseIsInvalid()) {
$validator->errors()->add('field', 'Something is wrong with this field!');
}
});
}
Authorizing Form Requests
The form request class also contains an authorize
method. Within this method, you may check if the authenticated user actually has the authority to update a given resource. For example, you may determine if a user actually owns a blog comment they are attempting to update:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
Since all form requests extend the base Laravel request class, we may use the user
method to access the currently authenticated user. Also note the call to the route
method in the example above. This method grants you access to the URI parameters defined on the route being called, such as the {comment}
parameter in the example below:
Route::post('comment/{comment}');
If the authorize
method returns false
, a HTTP response with a 403 status code will automatically be returned and your controller method will not execute.
If you plan to have authorization logic in another part of your application, return true
from the authorize
method:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
Customizing The Validation Attributes
If you would like the :attribute
portion of your validation message to be replaced with a custom attribute name, you may specify the custom names by overriding the attributes
method. This method should return an array of attribute / name pairs:
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
$comment = Comment::find($this->route('comment'));
return $comment && $this->user()->can('update', $comment);
}
Prepare Input For Validation
If you need to sanitize any data from the request before you apply your validation rules, you can use the prepareForValidation
method:
use Illuminate\Support\Str;
/**
* Prepare the data for validation.
*
* @return void
*/
protected function prepareForValidation()
{
$this->merge([
'slug' => Str::slug($this->slug),
]);
}
php artisan make:request FieldRequest
Open app\Http\Request\FieldRequest File and implement below code in it
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class FieldRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
];
}
public function messages()
{
return [
'title.required' => 'A title is required',
'body.required' => 'A message is required',
];
}
}
Route::get('post/create', 'PostController@create');
Route::post('post', 'PostController@store');
<!DOCTYPE html>
<html>
<head>
<title>Form Request Validation In Laravel</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="text-center">
<h1>Form Request Validation In Laravel</h1>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-group col-sm-2">
</div>
<div class="form-group col-sm-8">
<div class="well">
<form method="post" action="{{url('post')}}">
@csrf
<div class="form-group col-sm-12">
<label for="title">Post Title</label>
<input id="title" type="text" class="form-control @error('title') is-invalid @enderror">
@error('title')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div class="form-group col-sm-12">
<label>Body</label>
<textarea class="form-control @error('body') is-invalid @enderror" type="textarea" name="body" ></textarea>
@error('body')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
</div>
<div class="form-group text-center">
<input class="btn btn-primary" type="submit" >
</div>
</form>
<div class="form-group col-sm-2"></div>
</div>
</div>
<br>
</div>
</body>
</html>
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\FieldRequest;
class PostController extends Controller
{
public function Create(){
return view('create');
}
public function store(FieldRequest $request)
{
$validated = $request->validated();
return 'done';
}
}
http://localhost/laraveldemoproject/public/post/create