Nguyễn Việt Dũng
Nguyễn Việt Dũng

Reputation: 3451

Error “Target class controller does not exist” when using 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:

Enter image description here

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.

How can I fix it?


Thanks to the answers, 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 answers.

Route::get('register', 'App\Http\Controllers\Api\RegisterController@register');

Upvotes: 344

Views: 609342

Answers (30)

phunsanit
phunsanit

Reputation: 31

Target class [ class name ] does not exist.

in /routes/web.php

you add that missing controller with

use App\Http\Controllers\ [ class name ] ;

Upvotes: 0

Yousha Aleayoub
Yousha Aleayoub

Reputation: 5618

No one said: composer dump-autoload

And then: php .\artisan optimize:clear

Upvotes: 1

Xakki
Xakki

Reputation: 180

Also, maybe need group into \App\Http\Kernel::$middlewareGroups its work for me

Upvotes: -2

bcag2
bcag2

Reputation: 2439

It is interesting to notice that since laravel v8, it is possible to use Route::controller(MyController::class)
https://laravel.com/docs/10.x/routing#route-group-controllers

In my case, I change previous laravel v7 coded

// CRUD Sample
Route::group(['prefix' => 'sample'], function ($router) {       // sample
    Route::get('/', 'SampleController@index');
    Route::get('/new', 'SampleController@create')->middleware('auth');
    Route::post('/store', 'SampleController@store')->middleware('auth');
    Route::group(['prefix' => '/edit'], function ($router) {            // sample/edit/{number}
        Route::get('/{number}', 'SampleController@edit')->middleware('auth');
        Route::get('/{number}/{migrate?}', 'SampleController@edit')->middleware('auth');
        Route::post('/', 'SampleController@store')->middleware('auth');
    });
});

to less verbose (v8 or more… v10 in my case) :

// CRUD Sample
Route::controller(SampleController::class)->prefix('sample')->group(function () {
    Route::get('/', 'index');
    Route::get('/new', 'create')->middleware('auth');
    Route::post('/store', 'store')->middleware('auth');
    Route::prefix('/edit')->middleware('auth')->group(function () {         // sample/edit/{number}
        Route::get('/{number}', 'edit');
        Route::get('/{number}/{migrate?}', 'edit');
        Route::post('/', 'store');
    });
});

then php artisan route:cache
then php artisan route:list
doesn't return anymore errors !-)

I don't understand why ->prefix doesn't works each time, for example :

// CRUD Licence
/* doesn't work
Route::controller(LicenceController::class)->middleware('auth')->prefix('licence')->group(function () {
    Route::get('/', 'index');
    Route::get('/new', 'new');
    Route::post('/new', 'insert');
});
*/
// works :
Route::controller(LicenceController::class, function () {
    Route::get('/licence', 'index')->middleware('auth');
    Route::get('/licence/new', 'new')->middleware('auth');
    Route::post('/licence/new', 'insert')->middleware('auth');
});

Upvotes: -1

TimeToCodeTheRoad
TimeToCodeTheRoad

Reputation: 7312

In the web.php (or api.php) in the routes folder, use/add that missing Controller class.

use App\Http\Controllers\<name of controller class>

Upvotes: 9

KalebC4
KalebC4

Reputation: 63

For me, I had to change my route naming to the more recently supported format, as others have mentioned:

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index']);

However, it continued to give me the same errors, until I ran this terminal command:

php artisan route:clear

Upvotes: 2

Anes
Anes

Reputation: 35

Please add the line

use App\Http\Controllers\RegisterController;

in the Web.php file.

Upvotes: 0

Abderrahman Fodili
Abderrahman Fodili

Reputation: 143

    "Target class [] does not exist."

for me it was because another developer in the team added the middleware method to the routes group and forgot to write its name

    ->middleware('')

Upvotes: 2

orups
orups

Reputation: 99

I faced the same error when running php artisan route:list. In my case I had deleted the recourse controller yet the route was still defined. I had to make sure the class in question was commented off in my routes/web.php.

Upvotes: 0

ZW23
ZW23

Reputation: 93

I tried everything, didn't work, until I tried this 2nd time restart server

php artisan cache:clear
php artisan optimize

php artisan route:list

Upvotes: 2

Nsamba Isaac
Nsamba Isaac

Reputation: 495

In my case, I had the same error, because I forgot to capitalize the first letter of controllers in the path.

So I changed

use App\Http\controllers\HomeController;

to this:

use App\Http\Controllers\HomeController;

Upvotes: 1

Ahmed Eid
Ahmed Eid

Reputation: 312

In Laravel 9, there isn't any need to add a namespace in RouteServiceProvider.

Instead of

Route::resource('tickets', 'TicketController');

use

Route::resource('tickets', TicketController::class);

Upvotes: 0

Nzubechukwu
Nzubechukwu

Reputation: 19

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.

Upvotes: 0

kirilclicks
kirilclicks

Reputation: 1677

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

Upvotes: 5

Hedayatullah Sarwary
Hedayatullah Sarwary

Reputation: 2834

I got the same error when I installed Laravel version 8.27.0: The error is as follows:

The error that I got.

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.

Upvotes: 16

Haron
Haron

Reputation: 2619

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 isn't any 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.

Upvotes: 28

Rohit Tagadiya
Rohit Tagadiya

Reputation: 3730

  • 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

  1. First go to the file: app > Providers > RouteServiceProvider.php

  2. In that file replace the line protected $namespace = null; with protected $namespace = 'App\Http\Controllers';

    Enter image description here

  3. Then add line ->namespace($this->namespace) as shown in image...

    Enter image description here

Upvotes: 85

Bruno Garcia
Bruno Garcia

Reputation: 111

For the solution, just uncomment line 29:

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

in the app\Providers\RouteServiceProvider.php file.

Just uncomment line 29

Upvotes: 8

user635568
user635568

Reputation: 306

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');
});

Upvotes: 7

stanley mbote
stanley mbote

Reputation: 1306

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.

Upvotes: 1

Chuck Le Butt
Chuck Le Butt

Reputation: 48758

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.

Upvotes: 8

einbulinda
einbulinda

Reputation: 77

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.

Upvotes: -1

Carlton
Carlton

Reputation: 5721

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

Upvotes: -1

Saroj Shrestha
Saroj Shrestha

Reputation: 2875

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');
});

Upvotes: 0

Noor Alalem
Noor Alalem

Reputation: 1

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.

Upvotes: -1

Tijani
Tijani

Reputation: 89

If you are using Laravel 8, just copy and paste my code:

use App\Http\Controllers\UserController;

Route::get('/user', [UserController::class, 'index']);

Upvotes: 8

Jatin Kaklotar
Jatin Kaklotar

Reputation: 505

Just uncomment the below line from RouteServiceProvider (if does not exists then add it):

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

Upvotes: 2

hariom nagar
hariom nagar

Reputation: 410

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'
    ]);
});

Upvotes: 2

Mirshod Mirjonov
Mirshod Mirjonov

Reputation: 131

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']);

Upvotes: 11

Jignesh Joisar
Jignesh Joisar

Reputation: 15115

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'));
    });
}

Upvotes: 23

Related Questions