问题
I'm trying to create a route with one optional parameter with Laravel 5.4.
Route :
Route::get('/run/{zone?}/id/{id}', 'RunController@show');
Controller :
class RunController extends Controller
{
public function show()
{
$route = \Route::current();
$zone = $route->parameter('zone') ?: 'default';
$id = $route->parameter('id');
Run::setZone($zone);
$run = Run::findOrFail($id);
return view('run.show')->with(['run' => $run]);
}
}
The url run/test/id/42
works like expected.
But with run/id/42
I got a nice NotFoundHttpException in RouteCollection.php
when I expect the same result than run/default/id/42
What did I missed ?
回答1:
Everything after the first optional parameter must be optional. If part of the route after an optional parameter is required, then that parameter becomes required.
In your case, the id/{id}
part of the route is non-optional, so the "optional" parameter before that section of the route becomes required.
Laravel's routing is actually built on top of Symfony's routing, and this is a restriction in Symfony. According to the Symfony documentation here (emphasis mine):
Of course, you can have more than one optional placeholder (e.g.
/blog/{slug}/{page}
), but everything after an optional placeholder must be optional. For example,/{page}/blog
is a valid path, but page will always be required (i.e. simply/blog
will not match this route).
Additionally, another thing to watch out for:
Routes with optional parameters at the end will not match on requests with a trailing slash (i.e.
/blog/
will not match,/blog
will match).
回答2:
Optional parameters work when it is the last URL element so in your case it won't work.
来源:https://stackoverflow.com/questions/43666683/understand-laravel-route-with-optional-parameter