Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Fix router for array action within namespaced groups #34784

Closed
wants to merge 2 commits into from

Conversation

imanghafoori1
Copy link
Contributor

@imanghafoori1 imanghafoori1 commented Oct 10, 2020

While coding in a typical project I found that the router has an inconsistency:

This does not work in web.php since the root namespace of the group gets prepended to the imported controller.

use App\Http\Controllers\TasksController;

Route::middleware(['auth'])->get('{task}/edit', [TasksController::class, 'edit']);

Error: App\Http\Controllers\App\Http\Controllers\TasksController does not exist.

But the original feature does not expect that: #24385

===========

There are 2 solution:

1- if we add a backslash at the start of controller '\'.TasksController:

Route::middleware(['auth'])->get('{task}/edit', ['\\'.TasksController::class, 'edit']);

2- we call the middleware method "After" controller

Route::get('{task}/edit', [TasksController::class, 'edit'])->middleware(['auth']);
  • I added a test to demonstrate the bug, without the change it does not pass.
  • To be fully backward-compatible it only adds backslash if it is not already included.

@GrahamCampbell
Copy link
Member

I think this is a major breaking change? Stops people from using namespaces?

@GrahamCampbell
Copy link
Member

That said, I agree the namespacing feature maybe isn't so useful anymore if people are mostly using class notation now, so we maybe could consider making your proposed behaviour the default in Laravel 9, and possibly going further and removing namespacing stuff.

@imanghafoori1
Copy link
Contributor Author

imanghafoori1 commented Oct 11, 2020

I remember, the possibilty of referencing methods in routes was added in 5.6 in the PR #24385
And I always used it like this:
Route::get(...) -> middleware(... ) ;

The unexpected thing happed when I only turned the method calls around:
Route::middleware(...) ->get(...) ;

The second way requires '\'. but not the first way.
And that is because the the get method called behind the scenes is different when you do the it the second way.

@imanghafoori1 imanghafoori1 reopened this Oct 11, 2020
@imanghafoori1 imanghafoori1 force-pushed the fix_router branch 2 times, most recently from 68888b7 to 98837ce Compare October 11, 2020 03:54
@imanghafoori1
Copy link
Contributor Author

imanghafoori1 commented Oct 11, 2020

@GrahamCampbell
I changed the implementation so that it only adds the backslash only it is not at the beginning to be fully backward compatible.
and I also added a test to simulate user code for both cases:

Route::middleware('auth')->get('{task}/edit', ['\\'.TasksController::class, 'edit']);
Route::middleware('auth')->get('{task}/edit', [     TasksController::class, 'edit']);

I think with the route cache the production performance will be the same.

@taylorotwell
Copy link
Member

I'm confused. Of course it doesn't work. You said your RouteServiceProvider defines a namespace? So, it will be prepended. This is exactly how Laravel 7.x worked.

@taylorotwell
Copy link
Member

No plans to change this behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants