Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

londoh's avatar

[L5] Porting L4 Controllers and Namespaces

I hope this is to do with my lack of understanding of L5 controller namespaces:

I have an existing L4 app and would like to bring it into L5

my app is entirely within its own folder so:

app/Myapp app/Myapp/Widgets app/Myapp/Controllers etc its namespaced and works ok in L4

I've set psr4 autoload in composer.json

I'm looking to use BootstrapCMS as a basis and I'll use it as an example altho it may not be relevant to the more generic question

in Http/Providers/RouteServiceProvider Graham Campbell sets a namespace so:

class RouteServiceProvider extends ServiceProvider
{
    /** ...
     */
    protected $namespace = 'GrahamCampbell\BootstrapCMS\Http\Controllers';

I now set a basic route in Http/routes.php like this:

Route::get('/', ['uses' => 'Myapp\Controllers\WidgetController@index']);

when I access that route I get this ReflectionException:

Class GrahamCampbell\BootstrapCMS\Http\Controllers\Myapp\Controllers\WidgetController does not exist

I've read the L5 docs and matt stauffer's upgrade blog esp. controllers, namespaces and RouteServiceProvider But I dont see any override for location of Myapp controllers under these circumstances. In fact it seems I am now forced to place all my controllers under Http/Controllers.

Surely I am mistaken here? can somebody please show how

thanks

l. (no preview in here so apologies if my markdown is markwrong)

0 likes
20 replies
londoh's avatar

@kfirba - yea thanks for reply, but i read it. I quote:

Next, move all of your controllers into the app/Http/Controllers directory.

Its bit that I was trying to avoid.

How can I leave my existing controllers in their existing position?

thepsion5's avatar

Set the namespace property for the controllers to MyApp\Controllers and then reference them in your routes without the namespace prefix like so:

Route::get('/', ['uses' => 'WidgetController@index']);

That should work, assuming your autoloading it set up properly.

kfirba's avatar

@londoh Take a look at App/Providers/RouteServiceProvider.php. You can find there:

    protected $namespace = 'App\Http\Controllers';

Try changing that and report back.

londoh's avatar

@thepsion5 - they are set as you suggest, and work in L4

@kfirba - if you read my post you'll see that I explained that has already been set - because I have dropped my app into the pre exisiting CMS i referenced

If I change $namespace property then my code works but the CMS barfs

and I dont see how to allow 2 controller namespaces. I'm sure there must be...

kfirba's avatar

@londoh My bad. Have you tried to prefix your controller with \:

Route::get('/', ['uses' => '\Myapp\Controllers\WidgetController@index']);
londoh's avatar

yea already - doesnt work.

it doesnt work because RouteServiceProviders appears to lock all controllers from routes to that that $namespace

I'm sure there must be a way to have controllers in several namespaces, but how?

londoh's avatar

sorry, to explain further, if I do as you suggest I get:

Class GrahamCampbell\BootstrapCMS\Http\Controllers\Myapp\Controllers\WidgetController does not exist

(note the double slash) gah I hate (dont get) md it doesnt show the double slash which appears between ...Http\Controllers and Myapp\Controllers...

kfirba's avatar

@londoh I will try to figure out a solution. However, for now, you can just move your controllers to the: GrahamCampbell\BootstrapCMS\Http\Controllers namespace. (You will need to force a GrahamCampbell namespace for your app and mimic the BootstrapCMS folder. Not the best solution I guess.)

londoh's avatar

thanks for reply.

I dont really want to shift stuff about, so grateful if you can figure out a solution

I kinda feel this should be very easy, and I must be missing something obvious. But I dont see it

kfirba's avatar

@londoh I'm not sure if I'm missing something but the only solution I see at the moment is altering your folders like I said before.

I think that a good solution would be to have the option to specify a substitute namespace when registering the routes. Maybe I will make a pull request.

londoh's avatar

yea, but I dont want to have to alter my folder structure, its not totally simple - there will be conflicts in this instance. And really since we now have namespacing in php I shouldnt have to.

and I forgot to say earlier that setting a route namespace doesnt override this either.

pull request? well unless we missed something it could be necessary

kfirba's avatar

@londoh Can you please tell me where it throws the error at? Which line of code throws the:

Class GrahamCampbell\BootstrapCMS\Http\Controllers\Myapp\Controllers\WidgetController does not exist

londoh's avatar

I have stack trace, can post later but gone to eat just now.

But it's easy enough to reproduce. Just stick SomeController.php in app/Somedir/Controllers and set a route

wells's avatar

Did you run artisan dump-autoload?

kfirba's avatar

@londoh Hello there.

Please try something like:

Route::group(['namespace' => 'My/Namespace'], function() {
    // register routes here for that namespace
});

Also, it seems that if you set the namespace property on the service provider to null you can then explicitly choose namespace for each route (including controllers).

londoh's avatar

Hi @kfirba

Thanks for still thinking about it! I'm not at my dev machine just just now but...

I couldn't get group namespace as you suggest to work in this case

As you remember I was using graham Campbell bootstrapcms as a basis. I think maybe the issue arises once an app namespace has been set - which that Cms code does, and after that anything in http/routes is relative to the global app namespace. So my controllers in myapp/controllers don't work.

But I think I probably did find a way round it: by setting route namespace via a serviceprovider, inject Router into boot method, then do router->group(namespace) kinda thing (excuse syntax - on a phone)

Anyway that seems to work but I haven't really tested it much yet, or fully understood why tbh

Tnx

l.

kfirba's avatar

@londoh I see.

BTW, have you tried setting the namespace to null and then address all your routes with full namespace path (process can be eased by using the Route::group() method). To test that, I saw that the package that you are using is pulling aRouteServiceProviderso just go in there and set thenamespace` property to null.

londoh's avatar

you are correct in the package is setting namespace in RouteServiceProvider

and in doing so (I assume that) laravel is grabbing\enforcing the app\namespace based on it.

Yes (as I posted) I have tried resetting RouteServiceProvider->namespace prop to Myapp and null. And indeed I can get my controllers available to routes by doing this.

But unsetting or resetting that $namespace causes the cms package to fail for same reason

I think the solution I posted earlier will work. I'll post code when I get a minute to check it later

l.

kfirba's avatar

@londoh

I don't really know how your cms routes are set, but if you have access to them, you can simply wrap them with a group route set with the namespace that you have just changed.

Please or to participate in this conversation.