Laravel Route Issues with Route Order in Web.Php

Laravel Route issues with Route order in web.php

When accessing a route, Laravel goes through your list of routes top to bottom, until it finds one that 'matches' at which point this route is 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'); comes first so it would be selected.

As the previous answers correctly state, placing the /blog/bin route above the /blog/{id} route would solve the problem. However, this 'solution' leaves you open to a similar mistake in the future (when, for example, defining a /blog/example route and accidentally placing it under /blog/{id}). In addition, I personally think it is not very elegant to have the functioning of your routes depend on the order to place them in.

In my opinion, when possible, a more robust solution is to restrict the possible values that are accepted by /blog/{id} with a regex constraint.

For example, if you are using a numeric ID for your blogposts, you know that you only want to use route /blog/{id} if id is a number. Thus, you would define your route as follows:

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

Of course this is often not a possibility, for example if you use the post title as an id, but if there is some way to differentiate a post id from any other /blog/foo route, then this would be a possibility.

Changing the order of routes in web.php file causes my application to throw a 404 error in Laravel 9

As @Marleen says you have to set most exact routes first.
In your case it should look like

//Routes for Categories
Route::get('categories/edit/{category}',[CategoryController::class, 'edit'])->name('edit_category');
Route::put('categories/update/{category}',[CategoryController::class, 'update'])->name('update_category');
// ^ 3 segment routes are set first
Route::get('categories/create',[CategoryController::class, 'create'])->name('create_category');
Route::get('categories/destroy',[CategoryController::class, 'destroy'])->name('destroy_category');
Route::post('categories/store',[CategoryController::class, 'store'])->name('store_category');
// ^ 2 segment routes with exact match are set second
Route::get('categories/{category}',[CategoryController::class, 'show'])->name('show_category');
// ^ 2 segment routes with dynamic match is set third
Route::get('categories',[CategoryController::class, 'index'])->name('categories');
// ^ 1 segment route with exact match is set fourth

Laravel 8 route order from bottom to top

A short explanation for this would be that each call to Route::{verb} creates a new route entry under your route collection (relevant code). {verb} ban be any HTTP verb e.g. get, or post etc. This entry is created under an array entry [{verb}][domain/url].

This means that when a new route is registered that matches the same URL with the same method it will overwrite the old one.

So in the case

Route::view('testing', 'welcome')->name('testingWelcome');
Route::get('testing',[TestingController::class, 'noParameter'])->name('testingNoParam');
Route::view('testing', 'dashboard')->name('testingDashboard');

Only the 3rd declaration actually "sticks". There are cases where multiple route definitions can match the same URL for example assume you have these routes:

Route::view('testing', 'welcome')->name('testingWelcome');
Route::get('testing/{optionalParameter?}',[TestingController::class, 'parameter'])->name('testingNoParam');
Route::view('testing/{otherParameter?}', 'dashboard')->name('testingDashboard');

In this case all 3 routes are added to the route collection, however when accessing URL example.com/testing the first matched route will be the one that will be called in this case the welcome view. This is because since all 3 routes are declared, once the router finds one matching route, it stops looking for more matches.

Note: There's generally no point in declaring multiple routes with the exact same URL so this is mainly an academic exercise. However there is often a use case for cases like e.g. model/{id} and model/list` to differentiate between getting info for a specific model and getting a list of models. In this case it's important to declare the routes as:

Route::get('model/list',  [ ModelController::class, 'list' ]);
Route::get('model/{id}', [ ModelController::class, 'view' ]);

However you can be more explicit in route declarations using:

Route::get('model/{id}',  [ ModelController::class, 'view' ])->where('id', 
'\d+');
Route::get('model/list', [ ModelController::class, 'list' ]);

in this case the order does not matter because Laravel knows id can only be a number and therefore will not match model/list

Why route in web.php conflicts due to a parameter passing in laravel 8

  1. You can change first route url by adding a string before or after {cat} like
    Route::get('/category/{cat}',[WebsiteController::class,'dbCategories'])->name('dbCategories')

Also , if you will change the ordering of routes , It will be work fine

Note: run php artisan route:clear command before testing

Laravel route resolving to a different method

Just want to reiterate what @TimLewis has suggested, I think you need to put this route:

Route::get('/case/create','create')->middleware('auth');

Above this route:

Route::get('/case/{id}','show')->middleware('auth');

But you could try using Laravel’s route resource so you don’t need to write out all the routes -

use App\Http\Controllers\HospitalCaseController;

Route::resource('case', HospitalCaseController::class);

Routing Error - how to call same route with out any error

So you have to order something like this,

Route::get('/', [HomeController::class, 'method'])->name('home.index');
Route::get('/dashboard', [HomeController::class, 'method'])->name('home');
Route::get('/{slug}', [Controller::class, 'method'])->name('view');

Let me know the results.

Laravel routes order

Sure, you are making a catchall route. The only issue with what you have is it will only match a route with a single segment:

yoursite.com/anything

but it will miss anything with more than 1 segment:

yoursite.com/anything/else/....

If you want to catch all you need a lil regex love to constrain the condition of the route parameter slug:

Route::get('{slug}', 'RouterController@process)->where('slug', '.*');

Now that route will catch anything URL.

There is also a fallback method on the router that will setup this route with the condition for you:

Route::fallback('yourAction');

Laravel 8 - Routing Problem - Missing Required Parameter

I really appreciate everyone's help.

How it seams, since I upgraded to Laravel 8, there is different routing ways.

I found problem:
It was in "edit-keywords.blade.php"

I had to change

<form action="/admin/edit-keywords/" method="post" id="setting_form" enctype="multipart/form-data">

To

 <form action="/admin/edit-keywords/{code}" method="post" id="setting_form" enctype="multipart/form-data">

And route also

  Route::post('/admin/edit-keywords/', [App\Http\Controllers\Admin\LanguageController::class, 'save_keywords'])->name('admin.save_keywords');

Changed to

  Route::post('/admin/edit-keywords/{code}', [App\Http\Controllers\Admin\LanguageController::class, 'save_keywords'])->name('admin.save_keywords');


Related Topics



Leave a reply



Submit