Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

How to use Laravel 7 style controller route definitions in Laravel 8

One of the most prominent changes in Laravel 8 is the (kind of) new way of defining controller routes. Before Laravel 8, if you wanted to define a route, you could do it like so.

Route::get('/home', 'HomeController@index']);

Here, as you can tell, UserController is the controller and index in the method of the controller we want to call on this route.

Now, this was used to work fine because, under the hood, Laravel used to append controller namespace using the $namespace property of the app/Providers/RouteServiceProvider like so.

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

So, the previous route definition would get resolved to the following.

Route::get('/home', 'App\Http\Controllers\HomeController@index']);

What’s changed in Laravel 8?

With the release of Laravel 8, the aforementioned way would not work. And if you do, you’ll get the following error.

Illuminate\Contracts\Container\BindingResolutionException
Target class [HomeController] does not exist.

This is because the $namespace property I talked about previously has been completely removed from app/Providers/RouteServiceProvider.

So, if you’ve just bootstrapped a new application using Laravel 8, you can start using the new syntax which encourages you to use Fully Qualified Class Names (FQCN) for controllers like so.

use App\Http\Controllers\HomeController;

Route::get('/home', [HomeController::class, 'index']);

Using old route definitions in Laravel 8

But if you’re like me who has just upgraded his/her Laravel application from 7.x to 8.x and still want to use the old syntax, you can add the $namespace property back to the app/Providers/RouteServiceProvider like so.

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

And apart from this, in the boot method of RouteServiceProvider, you’ll need to assign this namespace to the routes like so.

public function boot()
{
    $this->configureRateLimiting();

    $this->routes(function () {
        Route::middleware('web')
            ->namespace($this->namespace) // Assigning namespace
            ->group(base_path('routes/web.php'));

        Route::prefix('api')
            ->namespace($this->namespace) // Assigning namespace
            ->middleware('api')
            ->group(base_path('routes/api.php'));
    });
}

And after doing all these changes, everything should work fine!

In closing

In my opinion, the newer syntax is much nicer than the previous one as it encourages to use FQCNs and this can help navigate to controller classes if you’re using IDEs like PhpStorm. So, you should consider refactoring your code to using this syntax to make things more accessible.

But if you don’t want to do upgrade to the new syntax, fret not! I’ve already explained you the way. ;)

Learn the fundamentals of PHP 8 (including 8.1, 8.2, and 8.3), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?