Laravel Quickie: Basic Controllers
Tags: laravel, php, tutorial, webdev
Published: 2020-12-02 06:33:35

## 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.

```bash
php artisan make:controller {name}
```

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

```bash
php artisan make:controller ProductController
```

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

```php
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.

```php
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.

```php
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.

```bash
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].

```php
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.

```php
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.

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

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

```php
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.

```php
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.

```php
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.

```php
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](https://i.imgur.com/JluPjQX.png)

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](https://github.com/thinkverse/) under the [/laravel-quickie repository](https://github.com/thinkverse/laravel-quickie).

For this section take a gander under the [quickie-basic-controllers branch](https://github.com/thinkverse/laravel-quickie/tree/quickie-basic-controllers).

Thank you for reading and, till next time.

#### Note

The last code block won't render correctly, but as stated above. The code is available in the repository.

[free $100 digitalocean credit over 60 days]: https://m.do.co/c/646e3da9d160

[How to Install Laravel on DigitalOcean with 1-Click]: https://devdojo.com/bobbyiliev/how-to-install-laravel-on-digitalocean-with-1-click

[LaraSail]: https://devdojo.com/episode/laravel-on-digital-ocean-with-larasail

[called whenever the class is called as a function]: https://www.php.net/manual/en/language.oop5.magic.php#object.invoke

[imported using the **use** keyword]: https://www.php.net/manual/en/language.namespaces.importing.php