When talking about validation, we mostly mean POST requests. But GET requests also need to be validated! In this tutorial, let's see how we can do it in a couple of different ways.
Invalid GET values may be even more dangerous than POST ones. Changing the GET request value is much easier than POST because we see the value in the address bar.
And GET requests may have no value at all if when you visit the page for the first time, so we need to set the default value. All those cases below.
Default Fallback Value: request()
Helper
One way to validate the request is using the global helper request()
to add a default value.
For example, we have a table of users which by default is ordered by ID in ascending order. When you visit that page first time in the URL we won't have the parameter for ordering.
So if we have this code in Controller:
public function index(): View{ $sortDirection = request('direction'); $users = User::orderBy('id', $sortDirection)->paginate(10); return view('users.index', compact('users'));}
We will get an error:
Order direction must be "asc" or "desc".
This means we need to set a default value for the request
direction by just passing a second parameter.
public function index(): View{ $sortDirection = request('direction'); $sortDirection = request('direction', 'asc'); $users = User::orderBy('id', $sortDirection)->paginate(10); return view('users.index', compact('users'));}
And then we have table ordering in the expected way.
And if we add ?direction=desc
to the URL then we see the expected result as the table is ordered by ID in descending order.
$request->validate()
Looking at the same example above, we need to set not only the default value, but ensure that the value is ONLY "asc" or "desc". Otherwise, it would break again with the same error message:
Order direction must be "asc" or "desc".
For this, we can pass the Request $request
as a parameter and validate the request to check if the values for the direction
are correct.
use Illuminate\Validation\Rule; public function index(Request $request): View{ $request->validate([ 'direction' => [Rule::in(['asc','desc'])], ]); $sortDirection = request('direction', 'asc'); $users = User::orderby('id', $sortDirection)->paginate(10); return view('users.index', compact('users'));}
Form Request
To validate GET request inputs, we can also use the Form Request Classes, as they are not only strictly for forms.
In the form request, we have the same rule for the direction
value.
use Illuminate\Validation\Rule; class UserRequest extends FormRequest{ public function rules(): array { return [ 'direction' => [Rule::in(['asc','desc'])], ]; } public function authorize(): bool { return true; }}
And in the Controller, we use the Form Request instead of a regular Request class.
public function index(Request $request): View public function index(UserRequest $request): View { $users = User::orderby('id', $request->input('direction', 'asc'))->paginate(10); return view('users.index', compact('users'));}
Regular Expression Constraints in the Routes
The last validation option for the GET request variables can be done in the routes file, when defining the routes. We can chain the route with the where
method and use regular expressions.
For example, if we want to get a User in such a way:
Route::get('/user/{id}', function (int $id) { // ...})->where('id', '[0-9]+');
If we go to the route /user/1
, we get the User with ID of 1. But if we write any word like /user/username
, then we get a 404 error.
Also, Laravel has made some patterns for convenience, so that we shouldn't write regular expressions manually.
For example, the code above could be written like so:
Route::get('/user/{id}', function (int $id) { // ...})->whereNumber('id');
This will give the same result but the code in my opinion will be much easier to read.
You can find this feature and other convenience helpers for the regular expressions in the documentation.
No comments or questions yet...