Laravel 8 has just been released with a host of changes as well as functionality. One of the changes is the removal of the default route namespace route.
Although this change is backwards compatible, meaning older projects using Laravel 7.x can easily migrate to Laravel 8.x without changing anything, however new projects. apply Laravel 8 from the beginning to pay attention to this
Many developers face the problem of creating a project laravel 8, they try to load routes
and encounter some typical Exception
like this.
1 2 | Target class [PostController] does not exist. |
This problem is not a code error, however 99.9% of current Laravel guidelines are not suitable in this case because most of them rely on default namespace
to provide.
Change
Until Laravel 7, RouteServiceProvider.php
has the following code
1 2 3 4 5 6 | <span class="token variable">$protected</span> <span class="token variable">$namespace</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'AppHttpControllers'</span> <span class="token punctuation">;</span> Route <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">middleware</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'web'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">group</span> <span class="token punctuation">(</span> <span class="token function">base_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'routes/web.php'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
The above code tells Laravel that when loading routes
defined in routes/web.php
file, it will default to use the web
middleware and namespace AppHttpControllers
. More specifically, that is, every time you declare a new route in routes/web.php
file using the following syntax, Laravel will look for the controllers in the AppHttpControllers
folder:
1 2 | Route::get('posts', ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> ');s |
Larvel will use the AppHttpControllersPostController.php
However, when coming to Laravel 8, when you declare routes using the same syntax, Laravel will no longer look for the controller in the AppHttpControllers
. The main problem is here
How to fix
Well as above, we already know that with Laravel 8, there will be no main default namespace so Laravel will not know where to find your controller. There are three ways for you to tell Laravel this:
- Adding the default namespace is similar to what Laravel 7 was before.
- Use the path to the controller including the namespace when declaring a new route.
- Use the action (recommended) syntax
Manually add namespaces
This is extremely simple. Just go to the RouteServiceProvider.php
file and you will see the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">configureRateLimiting</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">routes</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Route <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">middleware</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'web'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">group</span> <span class="token punctuation">(</span> <span class="token function">base_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'routes/web.php'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Route <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">prefix</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'api'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">middleware</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'api'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">group</span> <span class="token punctuation">(</span> <span class="token function">base_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'routes/api.php'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
All you have to do is add 3 lines of code as below and Laravel will have an additional default namespace similar to Laravel 7:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">protected</span> <span class="token variable">$namespace</span> <span class="token operator">=</span> <span class="token single-quoted-string string">'AppHttpControllers'</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">boot</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">configureRateLimiting</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">routes</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> Route <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">middleware</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'web'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">group</span> <span class="token punctuation">(</span> <span class="token function">base_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'routes/web.php'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> Route <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token function">prefix</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'api'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">middleware</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'api'</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token keyword">namespace</span> <span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">group</span> <span class="token punctuation">(</span> <span class="token function">base_path</span> <span class="token punctuation">(</span> <span class="token single-quoted-string string">'routes/api.php'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
What did we just do? We declare the variable $namespace
and use it as the default namespace for both web and api routes.
If you run the application again, everything should be fine again.
Declare the route to use the full namespace
Using this method you would have to apply all of your routes, but the idea is simple: prepend your controller name with its own namespace. See the example below and you will understand immediately
1 2 | Route::get('posts', 'AppHttpControllers <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> '); |
Continue to try running my app again.
Use the action syntax
This is a recommended solution as it will be better supported by the IDEs because it can see exactly which class has been used. Instead of using the usual string-declared syntax, we can use this action syntax by specifying classes and methods for use in an array.
When using string syntax
1 2 | Route::get('posts', ' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> '); |
Instead use the action syntax
1 2 | Route::get('posts', [PostController::class, 'index']); |
Note we have to call PostController::class
instead of using string 'PostController'
so it will return 'AppHttpControllersPostController'
. The second value passed into the array is the name of the method we will use in the controller.
Again try running your application again and everything should work fine.
Conclude
With a few ways as above hopefully your project will not experience namespace errors and work well.
References:
https://medium.com/@litvinjuan/how-to-fix-target-class-does-not-exist-in-laravel-8-f9e28b79f8b4