'Target class controller does not exist - Laravel 8
Here is my controller:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterController extends Controller
{
public function register(Request $request)
{
dd('aa');
}
}
As seen in the screenshot, the class exists and is in the correct place:
My api.php
route:
Route::get('register', 'Api\RegisterController@register');
When I hit my register
route using Postman, it gave me the following error:
Target class [Api\RegisterController] does not exist.
Update:
Thanks to the answer, I was able to fix it. I decided to use the fully qualified class name for this route, but there are other options as described in the answer.
Route::get('register', 'App\Http\Controllers\Api\RegisterController@register');
Solution 1:[1]
You are using Laravel 8. In a fresh install of Laravel 8, there is no namespace prefix being applied to your route groups that your routes are loaded into.
"In previous releases of Laravel, the
RouteServiceProvider
contained a$namespace
property. This property's value would automatically be prefixed onto controller route definitions and calls to theaction
helper /URL::action
method. In Laravel 8.x, this property isnull
by default. This means that no automatic namespace prefixing will be done by Laravel." Laravel 8.x Docs - Release Notes
You would have to use the Fully Qualified Class Name for your Controllers when referring to them in your routes when not using the namespace prefixing.
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
// or
Route::get('/users', 'App\Http\Controllers\UserController@index');
If you prefer the old way:
App\Providers\RouteServiceProvider
:
public function boot()
{
...
Route::prefix('api')
->middleware('api')
->namespace('App\Http\Controllers') // <---------
->group(base_path('routes/api.php'));
...
}
Do this for any route groups you want a declared namespace for.
The $namespace
property:
Though there is a mention of a $namespace
property to be set on your RouteServiceProvider
in the Release notes and commented in your RouteServiceProvider
this does not have any effect on your routes. It is currently only for adding a namespace prefix for generating URLs to actions. So you can set this variable, but it by itself won't add these namespace prefixes, you would still have to make sure you would be using this variable when adding the namespace to the route groups.
This information is now in the Upgrade Guide
Laravel 8.x Docs - Upgrade Guide - Routing
With what the Upgrade Guide is showing the important part is that you are defining a namespace on your routes groups. Setting the $namespace
variable by itself only helps in generating URLs to actions.
Again, and I can't stress this enough, the important part is setting the namespace for the route groups, which they just happen to be doing by referencing the member variable $namespace
directly in the example.
Update:
If you have installed a fresh copy of Laravel 8 since version 8.0.2 of laravel/laravel
you can uncomment the protected $namespace
member variable in the RouteServiceProvider
to go back to the old way, as the route groups are setup to use this member variable for the namespace for the groups.
// protected $namespace = 'App\\Http\\Controllers';
The only reason uncommenting that would add the namespace prefix to the Controllers assigned to the routes is because the route groups are setup to use this variable as the namespace:
...
->namespace($this->namespace)
...
Solution 2:[2]
- Yes, in Laravel 8 this error does occur.
- After trying many solutions I got this perfect solution.
- Just follow the steps...
Case 1
We can change in api.php
and in web.php
files like below.
The current way we write syntax
is
Route::get('login', 'LoginController@login');
That should be changed to:
Route::get('login', [LoginController::class, 'login']);
Case 2
Solution 3:[3]
In Laravel 8 the default is to remove the namespace prefix, so you can set the old way in Laravel 7 like:
In RouteServiceProvider.php
, add this variable:
protected $namespace = 'App\Http\Controllers';
And update the boot
method:
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
});
}
Solution 4:[4]
In Laravel 8 you just add your controller namespace in routes\web.php
use App\Http\Controllers\InvoiceController; // InvoiceController is controller name
Route::get('invoice',[InvoiceController::class, 'index']);
Or go to: app\Providers\RouteServiceProvider.php
path and remove the comment:
protected $namespace = 'App\\Http\\Controllers';
Solution 5:[5]
The way to define your routes in Laravel 8 is either
// Using PHP callable syntax...
use App\Http\Controllers\HomeController;
Route::get('/', [HomeController::class, 'index']);
Or
// Using string syntax...
Route::get('/', 'App\Http\Controllers\HomeController@index');
A resource route becomes
// Using PHP callable syntax...
use App\Http\Controllers\HomeController;
Route::resource('/', HomeController::class);
This means that in laravel 8, there is no automatic controller declaration prefixing by default.
If you want to stick to the old way, then you need to add a namespace property in the
app\Providers\RouteServiceProvider.php
and activate in the routes method.
Solution 6:[6]
Laravel 8 updated RouteServiceProvider and it affects routes with the string syntax. You can change it like in previous answers, but the recommended way is using action syntax, not using route with string syntax:
Route::get('register', 'Api\RegisterController@register');
It should be changed to:
Route::get('register', [RegisterController::class, 'register']);
Solution 7:[7]
If you are using Laravel 8, just copy and paste my code:
use App\Http\Controllers\UserController;
Route::get('/user', [UserController::class, 'index']);
Solution 8:[8]
The Laravel 8 documentation actually answers this issue more succinctly and clearly than any of the answers here:
Routing Namespace Updates
In previous releases of Laravel, the RouteServiceProvider
contained a $namespace
property. This property's value would automatically be prefixed onto controller route definitions and calls to the action
helper / URL::action
method. In Laravel 8.x, this property is null
by default. This means that no automatic namespace prefixing will be done by Laravel. Therefore, in new Laravel 8.x applications, controller route definitions should be defined using standard PHP callable syntax:
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Calls to the action
related methods should use the same callable syntax:
action([UserController::class, 'index']);
return Redirect::action([UserController::class, 'index']);
If you prefer Laravel 7.x style controller route prefixing, you may simply add the $namespace
property into your application's RouteServiceProvider
.
Solution 9:[9]
I got the same error when I installed Laravel version 8.27.0: The error is as follow:
But when I saw my app/Providers/RouteServiceProvider.php
file, I had namespaces inside my boot method. Then I just uncommented this => protected $namespace = 'App\\Http\\Controllers';
Now my project is working
Solution 10:[10]
Also check your route web.php file if your RegisterController is properly in place..
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\RegisterController;
Route::get('/register',[RegisterController::class,'index'])->name('register');
Route::post('/register',[RegisterController::class,'store']);
Route::get('/', function () {
return view('test.index');
});
Solution 11:[11]
If you would like to continue using the original auto-prefixed controller routing, you can simply set the value of the $namespace property within your RouteServiceProvider and update the route registrations within the boot method to use the $namespace property:
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
});
}
Solution 12:[12]
For the solution, just uncomment line 29:
protected $namespace = 'App\\Http\\Controllers';
in the app\Providers\RouteServiceProvider.php
file.
Solution 13:[13]
Just uncomment the below line from RouteServiceProvider
(if does not exists then add it):
protected $namespace = 'App\\Http\\Controllers';
Solution 14:[14]
In Laravel 8 you can use it like this:
Route::group(['namespace'=>'App\Http\Controllers', 'prefix'=>'admin',
'as'=>'admin.', 'middleware' => ['auth:sanctum', 'verified']], function()
{
Route::resource('/dashboard', 'DashboardController')->only([
'index'
]);
});
Solution 15:[15]
On a freshly installed Laravel 8, in the App/Providers/RouteServices.php file:
/*
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
// protected $namespace = 'App\\Http\\Controllers';
Uncomment line
protected $namespace = 'App\\Http\\Controllers';
That should help you run Laravel the old-fashioned way.
In case you are upgrading from lower versions of Laravel to 8 then you might have to implicitly add line
protected $namespace = 'App\\Http\\Controllers';
in the RouteServices.php file for it to function the old way.
Solution 16:[16]
In case if you prefer grouping of these routes, you can do it as:
Route::group(['namespace' => 'App\Http\Controllers\Api'], function () {
Route::resource('user', 'UserController');
Route::resource('book', 'BookController');
});
Solution 17:[17]
One important thing to make sure you do after each change on the routes is clearing the cache (using laravel 9):
php artisan route:clear
Solution 18:[18]
Ensure you're using the correct name of the file in your route
for example:
If your controller file was named User.php, make that you're referencing it with User and not UserController
Solution 19:[19]
In Laravel 8 the way routes are specified has changed:
Route::resource('homes', HomeController::class)->names('home.index');
Solution 20:[20]
I had this error:
(Illuminate\Contracts\Container\BindingResolutionException Target class [App\Http\Controllers\ControllerFileName] does not exist.
Solution:
Just check your class name. It should be the exact same of your file name.
Solution 21:[21]
It happened to me when I was passing null to the middleware
function:
Route::middleware(null)->group(function () {
Route::get('/some-path', [SomeController::class, 'search']);
});
Passing []
for no middleware works. Or probably just remove the middleware
call if not using middleware :D
Solution 22:[22]
In the app/Providers folder, file RouteServiceProvider.php, change the protected $namespace
variable to
protected $namespace = 'App\\Http\\Controllers';
This will auto-comment the variable on save.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow