Laravel Quickie: Basic Controllers

Updated November 20, 2020・3 minute read Post By thinkverse
Laravel Quickie: Basic Controllers

Introduction

Welcome to Laravel Quickie!

In this section, we will go over the two basic controllers used in Laravel. The regular controller and the single-action controller.

Prerequisites

If you don't already have a Laravel project up and running. I'd suggest using a DigitalOcean Ubuntu Droplet. Use my affiliate code to get free $100 DigitalOcean credit over 60 days to spin up your own server!

If you do not have that yet. You can follow the How to Install Laravel on DigitalOcean with 1-Click tutorial on how to do set that up.

Alternatively, you could use the awesome LaraSail script to do the installation.

Regular Controller

The regular controller. A simple controller that is used in every Laravel application. Usually extending the BaseController that comes with a new Laravel project.

Generate Controller

To generate a regular controller instead of creating one manually you can use the following artisan command.

php artisan make:controller {name}

This command will generate a blank controller with the given name argument; for instance.

php artisan make:controller ProductController

Will generate a blank ProductController class located under app/Http/Controllers.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ProductController extends Controller
{
    //
}

Use Controller

To use our newly created controller we need to give it a method we can access somewhere in our code, our routes/web.php perhaps.

Let's add a quick public index() method on our new ProductController. We can return Laravel's default welcome view.

class ProductController extends Controller
{
    public function index()
    {
        return view('welcome');
    }
}

Now that our controller has been updated. We can update the route file to use that instead of returning the view.

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\ProductController;

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

Single Action Controller

Now a ProductController isn't really the place to return a welcome view from. That sounds like a single action. And that's a perfect way to use invokable controllers.

An invokable controller is a single action - or method, controller.

Generate Controller

We can use artisan to create those controllers as well using the --invokable flag. Let's generate a single action controller to return our view instead.

php artisan make:controller WelcomeController --invokable

This type of controller comes with a php magic method called __invoke. The method in question gets called whenever the class is called as a function.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class WelcomeController extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Request $request)
    {
        //
    }
}

Use Controller

Now we can move the return view statement to that controller instead.

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class WelcomeController extends Controller
{
    public function __invoke()
    {
        return view('welcome');
    }
}

Now our controllers look mostly the same except for the method signature. You might think we call this by simply adding __invoke as the second array value.

Route::get('/', [WelcomeController::class, '__invoke']);

While that works. There an even cleaner and shorter way to use single-action controllers.

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\WelcomeController;

Route::get('/', WelcomeController::class);

Controller Parameters

Let's finish by talking a bit about parameters. Used to pass information to our controller. The most basic usage is for URL parameters and the current incoming Request object.

As you've most likely noticed all generated controllers come with the Request already imported using the use keyword.

Let's add a new public show() method to our ProductController that takes that Request and a $product as parameters.

class ProductController extends Controller
{
    public function show(Request $request, string $product)
    {
        //
    }
}

We can now update our routes yet again and add a new /products/{product} route.

use Illuminate\Support\Facades\Route;

use App\Http\Controllers\WelcomeController;
use App\Http\Controllers\ProductController;

Route::get('/', WelcomeController::class);

Route::get('/products/{product}', [ProductController::class, 'show']);

Most others might use {id} here. But by using {product}` instead, illustrates the point that the name you give the route parameter will be the name of the controller parameter.

To see the arguments passed to the parameters. We use Laravel's built-in die dump function.

class ProductController extends Controller
{
    public function show(Request $request, string $product)
    {
        dd($product, $request);
    }
}

Passing our two arguments into the die dump function will give you similar output to this when visiting /products/laravel-quickie in a browser.

Screen shot of die dump output

The same would work for a single-action controller too, just add your parameters to the __invoke() method, and use it as a regular controller method.

Conclusion

I hope this little quickie answers any questions you have about basic controllers. And, as always, code is available on my GitHub under the /laravel-quickie repository.

For this section take a gander under the quickie-basic-controllers branch.

Thank you for reading and, till next time.

Still have a question?

Get help or discuss anything development/design related.

Start a discussion