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

# Sessies

> Hoe je met de HTTP-sessies van Laravel data bewaart tussen requests

## Wat is een sessie

HTTP is een stateless protocol. Dat betekent dat HTTP zelf geen mechanisme heeft om gebruikersinformatie te bewaren over meerdere requests heen.
De sessiefunctionaliteit van Laravel biedt een manier om gebruikersdata over meerdere requests te bewaren.

In de sessie sla je informatie op die je tussen requests wilt behouden, zoals de inlogstatus, producten in een winkelwagen en tussentijdse formulierinvoer.

## De sessiedriver instellen

De sessieconfiguratie staat in `config/session.php`.
Met de omgevingsvariabele `SESSION_DRIVER` (in het `.env`-bestand) wissel je van driver.

```ini theme={null}
SESSION_DRIVER=database
```

Laravel ondersteunt standaard de volgende drivers.

| Driver     | Omschrijving                                                               |
| ---------- | -------------------------------------------------------------------------- |
| `file`     | Opslaan als bestanden in `storage/framework/sessions`                      |
| `cookie`   | Opslaan in de browser als versleutelde cookies                             |
| `database` | Opslaan in een databasetabel                                               |
| `redis`    | Opslaan in Redis (snel)                                                    |
| `array`    | Opslaan in een PHP-array (voor tests; blijft niet bewaard tussen requests) |

<Info>
  In een standaard Laravel-project is de `database`-driver geconfigureerd. Voor de `database`-driver is een `sessions`-tabel nodig, maar die zit al in de standaardmigraties, dus je kunt hem meteen gebruiken.
</Info>

## Sessieserialisatie

In het applicatieskeleton van Laravel 13 staat `serialization` in `config/session.php` ingesteld op `json`. De interne standaard van het framework blijft `php`.

<Warning>
  Wijzig je van `php` naar `json`, dan worden alle sessies van actieve gebruikers ongeldig. Sla je PHP-objecten op in de sessie, dan kunnen er bovendien fouten optreden.
</Warning>

Wil je tijdens een upgrade de actieve sessies behouden, stel dan expliciet `php` in. Sla je geen PHP-objecten op in de sessie en is het geen probleem dat gebruikers opnieuw moeten inloggen, dan kun je voor betere beveiliging `json` gebruiken.

```php theme={null}
// config/session.php
'serialization' => 'php',
```

## Toegang tot de sessie

Er zijn twee manieren om de sessie te benaderen: via methoden op de `Request`-instantie en via de globale helper `session()`.

### Via de Request-instantie

Ontvang een `Request` als typehint in je controllermethode en benader de sessie via `$request->session()`.

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

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\View\View;

class DashboardController extends Controller
{
    public function index(Request $request): View
    {
        $username = $request->session()->get('username');

        return view('dashboard', ['username' => $username]);
    }
}
```

### Via de globale helper `session()`

De helperfunctie `session()` kun je overal aanroepen, in controllers, views enzovoort.

```php theme={null}
// Een waarde ophalen
$value = session('key');

// Ophalen met een standaardwaarde
$value = session('key', 'standaardwaarde');

// Een waarde opslaan
session(['key' => 'value']);
```

<Tip>
  Bij beide manieren kun je in tests verifiëren met de methode `assertSessionHas`. In controllers maakt `$request->session()` de afhankelijkheden expliciet en dus overzichtelijker.
</Tip>

## Met de sessie werken

### Data ophalen

```php theme={null}
// Ophalen op basis van een sleutel
$value = $request->session()->get('key');

// Een standaardwaarde opgeven
$value = $request->session()->get('key', 'default');

// De standaardwaarde als closure opgeven
$value = $request->session()->get('key', function () {
    return 'default';
});

// Alle sessiedata ophalen
$data = $request->session()->all();
```

### Controleren of data bestaat

```php theme={null}
// true als de waarde bestaat en niet null is
if ($request->session()->has('user_id')) {
    // ...
}

// true zolang de sleutel bestaat, ook bij null
if ($request->session()->exists('user_id')) {
    // ...
}

// true als de sleutel niet bestaat
if ($request->session()->missing('user_id')) {
    // ...
}
```

Let op het verschil tussen `has` en `exists`.

| Methode  | Bij `null`          |
| -------- | ------------------- |
| `has`    | Geeft `false` terug |
| `exists` | Geeft `true` terug  |

### Data opslaan

```php theme={null}
// Via de Request-instantie
$request->session()->put('user_name', 'Tanaka');

// Via de globale helper
session(['user_name' => 'Tanaka']);

// Toevoegen aan een array
$request->session()->push('cart.items', ['id' => 1, 'name' => 'Product A']);
```

### Data verwijderen

```php theme={null}
// Een specifieke sleutel verwijderen
$request->session()->forget('user_name');

// Meerdere sleutels in één keer verwijderen
$request->session()->forget(['user_name', 'cart']);

// Alle sessiedata verwijderen
$request->session()->flush();
```

## Flash-data

Flash-data is sessiedata die **alleen tijdens het volgende request** geldig is.
Je gebruikt het voor informatie die je maar één keer wilt tonen, zoals een bevestiging na een formulierinzending of een foutmelding.

### Data opslaan met `flash()`

```php theme={null}
$request->session()->flash('status', 'De post is opgeslagen.');
```

Deze data is beschikbaar tijdens het volgende request en wordt daarna automatisch verwijderd.

### Flash-data verlengen

```php theme={null}
// Alle flash-data één extra request bewaren
$request->session()->reflash();

// Alleen specifieke sleutels verlengen
$request->session()->keep(['status', 'message']);
```

### Flash-berichten tonen in Blade

```blade theme={null}
{{-- resources/views/layouts/app.blade.php --}}

@if (session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif

@if (session('error'))
    <div class="alert alert-danger">
        {{ session('error') }}
    </div>
@endif
```

<Tip>
  Zet de weergave van flash-berichten in je layoutbestand (bijvoorbeeld `layouts/app.blade.php`), dan worden ze consistent op alle pagina's getoond.
</Tip>

## Praktijkvoorbeeld: een bericht tonen na een formulierinzending

Na het versturen van een formulier een succesmelding in de sessie opslaan, redirecten en het bericht op de volgende pagina tonen — een klassiek patroon in webapps.

<Steps>
  <Step title="Routes definiëren">
    ```php theme={null}
    use App\Http\Controllers\PostController;

    Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
    Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
    Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
    ```
  </Step>

  <Step title="De controller implementeren">
    In de `store`-methode die de formulierinzending ontvangt, redirect je na het opslaan met een succesmelding.

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

    namespace App\Http\Controllers;

    use App\Models\Post;
    use Illuminate\Http\RedirectResponse;
    use Illuminate\Http\Request;
    use Illuminate\View\View;

    class PostController extends Controller
    {
        public function index(): View
        {
            $posts = Post::latest()->get();

            return view('posts.index', ['posts' => $posts]);
        }

        public function create(): View
        {
            return view('posts.create');
        }

        public function store(Request $request): RedirectResponse
        {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'body'  => 'required|string',
            ]);

            Post::create($validated);

            return redirect()
                ->route('posts.index')
                ->with('success', 'De post is aangemaakt.');
        }
    }
    ```

    `redirect()->with('success', '...')` is een shortcut om flash-data door te geven aan de redirectbestemming.
  </Step>

  <Step title="Het bericht tonen in de layout">
    Voeg het weergavegedeelte voor flash-berichten toe aan `resources/views/layouts/app.blade.php`.

    ```blade theme={null}
    <!DOCTYPE html>
    <html>
    <head>
        <title>My App</title>
    </head>
    <body>
        {{-- Flash-berichten --}}
        @if (session('success'))
            <div class="alert alert-success">
                {{ session('success') }}
            </div>
        @endif

        @if (session('error'))
            <div class="alert alert-danger">
                {{ session('error') }}
            </div>
        @endif

        @yield('content')
    </body>
    </html>
    ```
  </Step>

  <Step title="De view voor de overzichtspagina maken">
    ```blade theme={null}
    {{-- resources/views/posts/index.blade.php --}}

    @extends('layouts.app')

    @section('content')
    <h1>Overzicht van posts</h1>

    @foreach ($posts as $post)
        <div>
            <h2>{{ $post->title }}</h2>
            <p>{{ $post->body }}</p>
        </div>
    @endforeach
    @endsection
    ```

    Nadat de post is opgeslagen en je bent geredirect, verschijnt bovenaan deze overzichtspagina eenmalig het bericht "De post is aangemaakt.".
  </Step>
</Steps>

### Patroon in combinatie met validatiefouten

Bij een mislukte validatie combineer je dit met `back()->withErrors()`.
Laravel bewaart bij een mislukte validatie de fouten automatisch als flash-data, zodat je in Blade de variabele `$errors` kunt gebruiken.

```php theme={null}
public function store(Request $request): RedirectResponse
{
    $validated = $request->validate([
        'title' => 'required|string|max:255',
        'body'  => 'required|string',
    ]);

    Post::create($validated);

    // Bij succes: redirect met een flash-bericht
    return redirect()
        ->route('posts.index')
        ->with('success', 'De post is aangemaakt.');

    // Bij een mislukte validatie voert Laravel automatisch back()->withErrors()->withInput() uit
}
```

```blade theme={null}
{{-- Formulierpagina --}}

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<form method="POST" action="{{ route('posts.store') }}">
    @csrf

    <div>
        <label for="title">Titel</label>
        <input
            id="title"
            type="text"
            name="title"
            value="{{ old('title') }}"
        />
        @error('title')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <div>
        <label for="body">Inhoud</label>
        <textarea id="body" name="body">{{ old('body') }}</textarea>
        @error('body')
            <span>{{ $message }}</span>
        @enderror
    </div>

    <button type="submit">Plaatsen</button>
</form>
```

<Warning>
  `flush()` verwijdert alle data uit de sessie. Ook de inlogstatus gaat dan verloren; wil je alleen bepaalde gebruikersdata verwijderen, geef dan met `forget()` specifieke sleutels op.
</Warning>

## Volgende stap

<Card title="Validatie" icon="check-circle" href="/nl/validation">
  Bekijk hoe je formulierinvoer valideert.
</Card>


## Related topics

- [HTTP-tests](/nl/http-tests.md)
- [Upgradegids van Laravel 12 naar 13](/nl/blog/upgrade-12-to-13.md)
- [Agent loop](/nl/packages/laravel-copilot-sdk/agent-loop.md)
- [Illuminate\Support\Manager — anatomie van het driversysteem](/nl/advanced/manager.md)
- [Redis](/nl/redis.md)
