问题
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}/blogis a valid path, but page will always be required (i.e. simply/blogwill 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,/blogwill 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