Multiple routes defaults to controller in Laravel

≡放荡痞女 提交于 2020-01-16 18:42:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!