Laravel 5.5 URL参数默认值设置困惑:请求与中间件疑问
Hey there! Let's break down your confusion step by step—this part of Laravel's URL handling can feel a bit tricky at first, so it's totally normal to have these questions.
First: What "Current Request" Actually Means Here
You’re right to wonder about this! The "current request" Laravel refers to isn’t a new request you’re initiating when you call the route() helper. Instead, it’s the active HTTP request context your application is currently responding to.
For example: When a user visits your site (say, /posts/laravel/intro), Laravel boots up, processes that incoming request, and keeps track of its details (like route parameters, headers, etc.) throughout the request lifecycle. The URL defaults feature relies on this existing context to work.
Why Configure This in Middleware?
Middleware is the perfect place to set URL defaults because it runs early in the request lifecycle—right after the request is received, but before your controller or views handle the response. By setting defaults here, you ensure that every subsequent call to route() (in controllers, views, or even other middleware) within this request’s context can access those default values.
Let’s walk through a concrete example to make this clear:
Step 1: Define Your Route
First, create a route with parameters that you want to set defaults for:
// routes/web.php Route::get('/posts/{category}/{slug}', 'PostController@show')->name('post.show');
Step 2: Create & Configure the Middleware
Generate a new middleware to handle setting defaults:
php artisan make:middleware SetUrlDefaults
Open the new middleware file (app/Http/Middleware/SetUrlDefaults.php) and update the handle() method to set your default parameter values:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Routing\UrlGenerator; class SetUrlDefaults { protected $url; // Inject the URL generator via dependency injection public function __construct(UrlGenerator $url) { $this->url = $url; } public function handle($request, Closure $next) { // Here, we'll set a default for the `category` parameter. // We can pull the current category from the request's route (if it exists) // or fall back to a hardcoded default, like "laravel". $defaultCategory = $request->route('category') ?? 'laravel'; // Set the default value for the `category` parameter $this->url->defaults([ 'category' => $defaultCategory, ]); return $next($request); } }
Next, register this middleware in your web middleware group so it runs for all web requests. Open app/Http/Kernel.php and add it to the web array:
protected $middlewareGroups = [ 'web' => [ // ... other existing middleware (like EncryptCookies, VerifyCsrfToken) \App\Http\Middleware\SetUrlDefaults::class, ], ];
Step 3: Use the route() Helper Without Repeating Parameters
Now, when a user visits a URL like /posts/laravel/intro-to-routing, you can generate a new URL for another post in the same category without passing the category parameter:
// In your controller or view echo route('post.show', ['slug' => 'eloquent-basics']); // Output: /posts/laravel/eloquent-basics
If the user visits /posts/php/composer-tips, the same route() call will automatically use php as the category:
echo route('post.show', ['slug' => 'dependency-injection']); // Output: /posts/php/dependency-injection
Clearing Up Your Core Misunderstanding
You mentioned thinking the route() helper would work without an active request—but that’s the key point: URL defaults only work when there’s an active HTTP request context.
If you call route() outside of a request (like in an Artisan command or a console script), there’s no "current request" for Laravel to pull defaults from, so you’ll still need to pass all required parameters. But within a web request (where middleware runs), the defaults are tied to that request’s context, making your route() calls cleaner.
内容的提问来源于stack exchange,提问作者Deeven

