> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Controllers

> Uitleg over het maken van controllers in Laravel en de samenwerking met routing.

## Wat zijn controllers?

In plaats van alle logica voor het afhandelen van requests als closures in je routebestanden te definiëren, kun je dit gedrag organiseren met "controller"-klassen.
Controllers laten je gerelateerde request-logica bundelen in één klasse.

Een `UserController`-klasse kan bijvoorbeeld alle inkomende requests met betrekking tot gebruikers afhandelen, zoals het tonen, aanmaken, bijwerken en verwijderen van gebruikers.
Standaard worden controllers opgeslagen in de map `app/Http/Controllers`.

## Controllers maken

Om snel een nieuwe controller te genereren, gebruik je het Artisan-commando `make:controller`.
Alle controllers van je applicatie worden standaard opgeslagen in de map `app/Http/Controllers`.

```shell theme={null}
php artisan make:controller UserController
```

## Basiscontrollers

Een controllerklasse kan meerdere publieke methoden hebben die reageren op inkomende HTTP-requests.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * Toon het profiel van de opgegeven gebruiker
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
```

Zodra je een controllerklasse en methode hebt gemaakt, kun je als volgt een route naar de controllermethode definiëren:

```php theme={null}
use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);
```

Wanneer een inkomend request overeenkomt met de opgegeven route-URI, wordt de `show`-methode van de klasse `App\Http\Controllers\UserController` aangeroepen en worden de routeparameters aan de methode doorgegeven.

<Info>
  Controllers hoeven geen basisklasse te extenden. Het kan echter handig zijn om een basiscontrollerklasse te extenden met methoden die alle controllers moeten delen.
</Info>

## Single-action controllers

Als een controlleractie bijzonder complex is, kan het handig zijn om een hele controllerklasse aan die ene actie te wijden.
Dit bereik je door binnen de controller één enkele `__invoke`-methode te definiëren.

```php theme={null}
<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * Provisioneer een nieuwe webserver
     */
    public function __invoke()
    {
        // ...
    }
}
```

Bij het registreren van een route voor een single-action controller hoef je geen controllermethode op te geven.
Je geeft alleen de naam van de controller door aan de router.

```php theme={null}
use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);
```

Met de optie `--invokable` van het Artisan-commando `make:controller` kun je een invokable controller genereren.

```shell theme={null}
php artisan make:controller ProvisionServer --invokable
```

## Resource controllers

Als je elk Eloquent-model in je applicatie als een "resource" beschouwt, is het gebruikelijk om op elke resource dezelfde set operaties (CRUD) uit te voeren.
Met resource-routing van Laravel wijs je de typische routes voor aanmaken, lezen, bijwerken en verwijderen (CRUD) met één regel code toe aan een controller.

Met de optie `--resource` van het Artisan-commando `make:controller` kun je snel een controller maken die deze acties afhandelt.

```shell theme={null}
php artisan make:controller PhotoController --resource
```

Dit commando genereert een controller in `app/Http/Controllers/PhotoController.php`.
De controller bevat stub-methoden voor elke beschikbare resource-operatie.
Vervolgens registreer je een resource-route die naar de controller wijst:

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class);
```

Deze ene routeregel maakt meerdere routes aan die de verschillende acties op de resource afhandelen.
De gegenereerde controller bevat al stub-methoden voor elk van deze acties.

| HTTP-methode | URI                    | Actie   | Routenaam      |
| ------------ | ---------------------- | ------- | -------------- |
| GET          | `/photos`              | index   | photos.index   |
| GET          | `/photos/create`       | create  | photos.create  |
| POST         | `/photos`              | store   | photos.store   |
| GET          | `/photos/{photo}`      | show    | photos.show    |
| GET          | `/photos/{photo}/edit` | edit    | photos.edit    |
| PUT/PATCH    | `/photos/{photo}`      | update  | photos.update  |
| DELETE       | `/photos/{photo}`      | destroy | photos.destroy |

<Info>
  Voer het commando `php artisan route:list` uit om snel een overzicht van de routes van je applicatie te bekijken.
</Info>

### Gedeeltelijke resource-routes

Bij het declareren van een resource-route kun je een subset van acties opgeven die de controller moet afhandelen.

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);
```

### API-resource-routes

Bij het declareren van resource-routes voor een API wil je vaak routes uitsluiten die HTML-templates tonen, zoals `create` en `edit`.
Met de `apiResource`-methode worden deze twee routes automatisch uitgesloten.

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::apiResource('photos', PhotoController::class);
```

## Middleware-attributen

Je kunt ook middleware aan een controller toewijzen met PHP-attributen.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Attributes\Controllers\Middleware;

#[Middleware('auth')]
#[Middleware('log', only: ['index'])]
#[Middleware('subscribed', except: ['store'])]
class UserController
{
    // ...
}
```

Je kunt middleware-attributen ook op individuele controllermethoden zetten. Middleware die je aan een methode toewijst, wordt toegevoegd aan de middleware die je op klasseniveau hebt toegewezen.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Routing\Attributes\Controllers\Middleware;

#[Middleware('auth')]
class UserController
{
    #[Middleware('log')]
    #[Middleware('subscribed')]
    public function index()
    {
        // ...
    }

    #[Middleware(static function (Request $request, Closure $next) {
        // ...

        return $next($request);
    })]
    public function store()
    {
        // ...
    }
}
```

## Dependency injection

### Constructor injection

De servicecontainer van Laravel wordt gebruikt om de afhankelijkheden van alle Laravel-controllers te resolven.
Daarom kun je de afhankelijkheden die je controller nodig heeft via type-hints opgeven in de constructor van de controller.
De gedeclareerde afhankelijkheden worden automatisch geresolved en in de controllerinstantie geïnjecteerd.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * Maak een nieuwe controllerinstantie aan
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}
```

### Method injection

Naast constructor injection kun je ook de afhankelijkheden van controllermethoden via type-hints opgeven.
Een veelvoorkomende use case voor method injection is het injecteren van een `Illuminate\Http\Request`-instantie in een controllermethode.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Sla een nieuwe gebruiker op
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->name;

        // Logica om de gebruiker op te slaan...

        return redirect('/users');
    }
}
```

Als een controllermethode ook invoer uit routeparameters verwacht, zet je de route-argumenten na de overige afhankelijkheden.
Stel bijvoorbeeld dat je route als volgt is gedefinieerd:

```php theme={null}
use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);
```

Door je controllermethode als volgt te definiëren, kun je `Illuminate\Http\Request` type-hinten en tegelijkertijd toegang krijgen tot de `id`-parameter:

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Werk de opgegeven gebruiker bij
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // Logica om de gebruiker bij te werken...

        return redirect('/users');
    }
}
```

<Tip>
  Door dependency injection te gebruiken, kun je bij het testen gemakkelijker mocks injecteren, wat de testbaarheid van je code verbetert.
</Tip>

## Volgende stappen

<Card title="Routing" icon="route" href="/nl/routing">
  Bekijk opnieuw hoe je routes definieert en hoe ze met controllers samenwerken.
</Card>


## Related topics

- [Routing](/nl/routing.md)
- [PHP-attributes voor controllers](/nl/advanced/controller-attributes.md)
- [FAQ over de nieuwe appstructuur van Laravel 11+](/nl/advanced/app-structure-faq.md)
- [Introductie van Laravel Wayfinder](/nl/blog/wayfinder-introduction.md)
- [Eloquent API-resources](/nl/eloquent-resources.md)
