问题
I want to be able to get to an article by a short-link, like this articles/ID
, but I also want to get there with the full link articles/ID/category/slug
. But I can not get the following to work:
// Route file:
Route::pattern('id', '[0-9]+');
Route::pattern('cat', '^(?!create).*');
Route::pattern('slug', '^(?!edit).*');
Route::get('articles/{id}/{cat?}/{slug?}', ['as' => 'articles.show', 'uses' => 'ArticlesController@show']);
// Controller file:
public function show($id, $cat = null, $slug = null)
{
dd('1: ' . $cat . ' | 2:' . $slug);
}
The following link articles/28/ullam/vel-repellendus-aut-est-est-esse-fugiat
gives the result:
string(53) "1: ullam/vel-repellendus-aut-est-est-esse-fugiat | 2:"
I don't understand why it's not split, if I remove the ?
in my route definition it works.
I have tried this solution https://stackoverflow.com/a/21865488/3903565 and that works, but not when directed at a controller. Why?
Update; I ended up rearranging my routes file:
Route::pattern('id', '[0-9]+');
// Articles
Route::get('articles/create', ['as' => 'articles.create', 'uses' => 'ArticlesController@create']);
Route::get('articles/edit/{id}', ['as' => 'articles.edit', 'uses' => 'ArticlesController@edit']);
Route::get('articles/{id}/{category?}/{slug?}', ['as' => 'articles.show', 'uses' => 'ArticlesController@show']);
Route::get('articles/{category?}', ['as' => 'articles.index', 'uses' => 'ArticlesController@index']);
Route::resource('articles', 'ArticlesController', ['only' => ['store', 'update', 'destroy']]);
回答1:
The problem is only in the lookahead patterns.
You need $
and class excluding /
in order to make it work.
So here they are:
Route::pattern('id', '[0-9]+');
Route::pattern('cat', '^(?!create$)[^/]*');
Route::pattern('slug', '^(?!edit$)[^/]*');
Route::get('articles/{id}/{cat?}/{slug?}', function($id, $cat, $slug)
{
dd($id.': ' . $cat . ' | 2:' . $slug);
});
回答2:
Is that your only route? Or you have a different one pointing to show too? I just added this one as my first route:
Route::get('articles/{id}/{cat?}/{slug?}', function($id, $cat, $slug)
{
dd($id.': ' . $cat . ' | 2:' . $slug);
});
And got this result:
28: ullam | 2:vel-repellendus-aut-est-est-esse-fugiat
Change the order of your routes to have the first one as your most specific routes and the last as your most generic one. Also, if you have any patterns, they can be inteferring with your results.
Looks like there's a problem with some patterns and optional parameters (?), so if you do
Route::pattern('id', '[0-9]+');
Route::pattern('cat', '^(?!create).*');
Route::pattern('slug', '^(?!edit).*');
Route::get('articles/{id}/{cat}/{slug}', function($id, $cat, $slug)
{
dd($id.': ' . $cat . ' | 2:' . $slug);
});
It will work fine. My advice is to not reuse routes too much, if you have an specific route, you create a route command for it and add it before your most generic ones:
Route::get('articles/{id}/create', function($id)
{
dd('this is the create route');
});
Route::get('articles/{id}/{cat}/{slug}', function($id, $cat, $slug)
{
dd($id.': ' . $cat . ' | 2:' . $slug);
});
The cost of creating new routes is low in comparison to the complexity of looking to regex patterns and try to find your way amongst them. Having new collaborators on projects, or even for your future self, the simpler, the better.
In Laravel 4.3 you'll have access to route caching, which makes routes being fired almost instantly.
来源:https://stackoverflow.com/questions/25752100/multiple-routes-defaults-to-controller-in-laravel