Registering Database Migrations in Laravel Packages
When a Laravel package needs its own database tables, its maintainers must decide how the host application will find the package’s migration…
In a Laravel route, a route parameter is a named placeholder in the URL path. Laravel reads the matching part of the path and passes its value to the route’s controller or closure, the code that handles the request. A required parameter means the URL must include that part. An optional parameter lets the route match when that part is missing.
Write a required parameter in curly braces, as {id}, and an optional one with a question mark, as {name?}. You can add a where constraint, a regular expression that limits which values match. These rules determine whether Laravel runs the route’s handler or returns a 404 response. The Laravel quick reference also shows this syntax.
A route with {id} requires one path segment in that position. For example:
use Illuminate\Support\Facades\Route;
Route::get('/users/{id}', function (string $id) {
return 'User '.$id;
});
For /users/42, Laravel passes the string 42 to the closure as $id. A request to /users does not match because it lacks the required segment. Laravel passes the URL value to the handler, but it does not automatically look up a database record or check that the value belongs to a real user.
Put the handler’s arguments in the same order as the route placeholders. For a route with multiple parameters, Laravel passes their values in route order:
Route::get('/users/{user}/posts/{post}', function (string $user, string $post) {
// $user contains the first path segment; $post contains the second.
});
The Laravel route parameter examples show how route placeholders correspond to handler arguments.
Add ? to a parameter name so the route matches when the URL omits that segment. Give the matching handler argument a default value, usually null:
Route::get('/users/{name?}', function (?string $name = null) {
return $name ?? 'All users';
});
This route matches both /users and /users/Ada. When the URL leaves out the optional part, Laravel passes null. The handler needs a default value for that argument; otherwise, PHP can report a missing argument. You can use a different default, such as a string, if the handler should use a specific value when the URL omits the part.
The URL path supplies path parameters; the query string supplies query-string values. /users/Ada supplies the name path parameter. /users?name=Ada sends name as query data. Make the route match the URL form your client sends.
where to restrict parameter valuesWithout a constraint, a route parameter matches any segment in the URL path. To require digits in {id}, use Laravel’s where method to reject other segments when Laravel checks the route:
Route::get('/users/{id}', function (string $id) {
return 'User '.$id;
})->where('id', '[0-9]+');
Now /users/42 matches, but /users/hello does not. If no route matches, Laravel returns a 404 response instead of passing hello to a handler that expects an ID. The pattern [0-9]+ means one or more digits.
You can constrain several parameters in one call:
Route::get('/users/{id}/{name}', function (string $id, string $name) {
// Handle the two captured values.
})->where([
'id' => '[0-9]+',
'name' => '[A-Za-z]+',
]);
Choose a pattern that allows the values in your URLs. [A-Za-z]+ matches letters only, so it excludes spaces, digits, and hyphens; Ada-Lovelace does not match. The route constraint reference shows Laravel’s where syntax and examples.
A route with a broad parameter can also match a more specific path. For example, /users/{id} accepts the literal segment export unless a constraint excludes it. If the handler treats export as an ID, the lookup may fail. Put specific routes before routes with broad parameters, and restrict each parameter to values its handler accepts. A discussion of Laravel route matching explains this ordering pitfall.
Constraints also apply to optional parameters. If the supplied segment does not match its pattern, Laravel does not pass the invalid value to the handler; that route does not match the URL. An older Laravel.io discussion of optional constrained parameters describes defining one route with the segment and another without it. Because the discussion is old, check how your Laravel version behaves before using that workaround.
If a URL returns 404 unexpectedly or reaches the wrong handler, compare its path with the route placeholders, check each where pattern, and look for nearby routes that match the same path. This helps you tell whether Laravel failed to match the route or the handler produced the error.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com