Search

Invokable Controllers Example in Laravel 7

post-title

Hello Artisan

In this following tutorial i will discuss about single action controller in laravel. Do you ken what is single action controller and when to utilize this single action controller? 

Laravel provide a single action controller called invokable controller which contains a invoke method to perform a single task. So for doing only single task we can utilize this invokable controller. 

In this tutorial i will show you with a resplendent example that how and when we should utilize this invokable controller in laravel. Let's commence our tutorial.

In this example we will see how we can run multiple pages url from a single route. That mean we will see many pages like about, contact, terms etc from a single route. First have a look that how invoke method works.

Route::get('/{pages}','TestController');

Have a look this above code that there is no method. That mean it is a invokable controller. If there is no method in controller then the controller will call a method called invoke. Something like that

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function __invoke()
    {
        //some codes goes here
    }
}

So using this method we can do single action task. In this example tutorial we will see how to use this invoke method.

Suppose thing we have a 3 pages and we need to show it browser. So generally we need 3 routes like below.

Route::get('about', 'TestController@about');
Route::get('contact', 'TestController@contact');
Route::get('terms', 'TestController@terms');

So now we need 3 methods in our test controller to view those blade file. But using invokale controller we can do it using only one route and one method. Have a look.

Route::get('/{pages}','TestController')
       ->name('page');

Look there is no method so if you hit any page url in browser then it will call invoke method. So just open test controller and paste this below code.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function __invoke()
    {
        return view('pages.' . request()->segment(1));
    }
}

So in test controller invoke method we told to laravel that hey laravel you show us that pages which are in pages directory. See the below path

  1. resources/views/pages/contact.blade.php
  2. resources/views/pages/about.blade.php
  3. resources/views/pages/terms.blade.php

Hope you will understand. Now if you visit every url of page, it will work fine. Now if you want to make this page clickable route then follow below code.

<a class="nav-link" href="{{ route('page','contact') }}">{{ __('Contact') }}</a>
<a class="nav-link" href="{{ route('page','about') }}">{{ __('About') }}</a>
<a class="nav-link" href="{{ route('page','terms') }}">{{ __('Terms') }}</a>

Here first parameter is our route name and second parameter is page name. Now all are set to got. 

Now you can extend it bit more. It has some issues like if you visit unknown page url it will throw a error like view x not found but if you solve this issue then you have to add some bit more code like

Route::get('/{pages}','TestController')
       ->name('page')
       ->where('pages','about|contact|terms');

Here in where condition we are telling laravel that hey laravel you only load those blade file which i say. So laravel only load about, contact and terms. Now we have to change controller method like

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{
    public function __invoke($page)
    {
      return view('pages.' . $page);
    }
}

i hope you like this article.