Statamic Peak

Article

Laravel : Route Parameter

It is possible to define parameters into your routes. They are automatically threw into your controller function in the order they appear.

It is possible to define parameters into your routes. They are automatically threw into your controller function in the order they appear.

This allows us to have a single controller to handle routes with different contents. In our example, one single route for all our users, even if their id changes every time. Way more useful!

The function parameter does not need to have the same name as the road parameter.

<?php

use Illuminate\Http\Request;

Route::get('/user/{id}', function (Request $request, $id) {
    return 'User '.$id;
});

You need more general informations on Laravel? You'll find everything you need on the framework in my Laravel compendium (work in process) !

Optional parameters

The optional parameters allow you to not include some URL sections. This allows for example to see all users registered between 2 dates. When they are not defined, we can choose to not reduce the scope.

Be careful to not have duplicate inside your routes. Indeed, the routes /users/ and /users/{id?} will get in conflict if there is no parameter.

<?php

Route::get('/path/{start?}/{end?}', function ($start = null, $end = null)
{
    if (!$start) {
        // set start
    }
    if (!$end) {
        // set end
    }
    // do other stuff
}

Route parameters and Model

The URL parameters are often used to look for an existing model in our database. Because it happens regularly, Laravel offers an automatical model retrieval  based on the parameter name.

Be careful to give the model's name to the router parameter, if not it won't work. If this practice doesn't fit your needs, you can also make more explicit links.

<?php

use App\Models\User;

Route::get('/users/{user}', function (User $user) {
    return $user->email;
});

It is possible to retrieve a model from a field without using its id. There are 2 ways of doing it, when defining the route for a one-time use, or directly into the model to be used in each route.

<?php
// routes
use App\Models\Post;

Route::get('/posts/{post:slug}', function (Post $post) {
    return $post;
});

// ou dans votre modèle
public function getRouteKeyName()
{
    return 'slug';
}

When no model matches, Laravel automatically throws a 404, but we may want something else. In this situation, we can bring a Closure which will be threw instead. Good news, it even works with the routes in cache.

<?php
use App\Http\Controllers\LocationsController;
use Illuminate\Http\Request;

Route::get('/locations/{location:slug}', [LocationsController::class, 'show'])
        ->name('locations.view')
        ->missing(function (Request $request) {
            return Redirect::route('locations.index');
        });

Reminder: it's possible to cache your routes to drastically reduce their recording time at the framework start.

php artisan route:cache