Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Target class controller does not exist - Laravel 8

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 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." 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)
...

  • 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


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

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

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

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

use App\Http\Controllers\UserController;

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

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.