Laravel route problems with route order in web.php

I have a problem with routes in Laravel, I am following one tutorial and we have these routes listed in the web.php file

Route::get('/home', 'HomeController@index')->name('home');
Route::get('/blog', 'BlogController@index')->name('blog');
Route::get('/blog/create', 'BlogController@create');
Route::post('/blog/store', 'BlogController@store');
Route::get('/blog/{id}', 'BlogController@show');
Route::get('/blog/{id}/edit', 'BlogController@edit');
Route::patch('/blog/{id}', 'BlogController@update');
Route::delete('/blog/{id}', 'BlogController@destroy');
Route::get('/blog/bin', 'BlogController@bin');

      

The problem is the last blog path / bin, it doesn't work if I keep it below, but in the tutorial we moved it to the top of the other routes and then it worked fine, the instructor said there is some conflict in the routes and that the last route must be at the top to work, but didn't explain at all why? Can anyone explain in a little more detail, since I really just started with Laravel ...

+3


source to share


2 answers


When accessing a route, Laravel scans the list of routes from top to bottom until it finds one that "matches", at which point that route will be immediately selected.

In your example, when trying to access /blog/bin

using, GET

it has two potential matches:

Route::get('/blog/{id}', 'BlogController@show');

      

and

Route::get('/blog/bin', 'BlogController@bin');

      

In this case Route::get('/blog/{id}', 'BlogController@show');

, it will be first , so it will be selected.



As the previous answers suggest, placing the route /blog/bin

above the route /blog/{id}

will solve the problem. However, this "solution" leaves you open to a similar error in the future (when, for example, finds a route /blog/example

and accidentally puts it underneath /blog/{id}

). Also, I personally find it not very elegant for your routes to function depending on the order in which they are placed.

In my opinion, if possible, a more reliable solution is to limit the possible values ​​accepted /blog/{id}

with the regex constraint .

For example, if you are using a numeric id for your blog pages, you know you want to use the route /blog/{id}

if id

is number. So you define your route like this:

Route::get('/blog/{id}', 'BlogController@show')->where('id', '[0-9]+');

      

Of course, this is often not possible, for example if you use the message header like id

, but if there is some way to distinguish the message id

from any other route /blog/foo

, then this would be a possibility.

+4


source


You cannot determine the type in the route parameter. Therefore, Laravel guesses that the parameter can be integer or even a string.

Based on this, if you try to access /blog/bin

. Laravel will try to use a route /blog/{id}

with "bin" in the id param.



Here's a better answer than mine: https://laracasts.com/discuss/channels/laravel/order-of-routes-being-applied/replies/149199

+2


source







All Articles