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

# Session

> Wie Sie mit Laravels HTTP-Session Daten über mehrere Requests hinweg speichern

## Was ist eine Session

HTTP ist ein zustandsloses Protokoll: Es gibt keinen eingebauten Mechanismus, um Nutzerinformationen zwischen Requests zu erhalten.
Die Session-Funktion von Laravel liefert das Fehlende: Sie hält Daten über mehrere Requests hinweg.

Login-Status, Warenkorb-Inhalte, Zwischenstände bei mehrstufigen Formularen – alles, was zwischen Requests bestehen bleiben soll, legen Sie in der Session ab.

## Session-Treiber konfigurieren

Die Konfiguration liegt in `config/session.php`.
Der Treiber wird über die Variable `SESSION_DRIVER` in der `.env` gewählt.

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

Laravel bringt folgende Standard-Treiber mit:

| Treiber    | Kurzbeschreibung                                           |
| ---------- | ---------------------------------------------------------- |
| `file`     | Ablage als Datei in `storage/framework/sessions` (Default) |
| `cookie`   | Verschlüsseltes Cookie im Browser                          |
| `database` | Speicherung in einer DB-Tabelle                            |
| `redis`    | Speicherung in Redis (sehr schnell)                        |
| `array`    | PHP-Array (nur für Tests, überlebt keinen Request)         |

<Info>
  Die Laravel-Standardprojekte sind auf `database` gesetzt. Der `database`-Treiber benötigt die Tabelle `sessions`, die in den Standard-Migrationen bereits vorhanden ist.
</Info>

## Zugriff auf die Session

Es gibt zwei Wege: über die Methoden des `Request`-Objekts oder über den globalen Helper `session()`.

### Über die Request-Instanz

Deklarieren Sie `Request` als Parameter Ihres Controllers und rufen Sie `$request->session()` auf.

```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]);
    }
}
```

### Über den globalen Helper `session()`

Der Helper `session()` funktioniert überall – in Controllern, Views etc.

```php theme={null}
// Wert lesen
$value = session('key');

// Mit Default
$value = session('key', 'Default');

// Wert schreiben
session(['key' => 'value']);
```

<Tip>
  Beide Wege lassen sich in Tests mit `assertSessionHas` prüfen. Im Controller macht `$request->session()` die Abhängigkeit explizit.
</Tip>

## Session-Operationen

### Daten lesen

```php theme={null}
// Nach Schlüssel
$value = $request->session()->get('key');

// Mit Default
$value = $request->session()->get('key', 'default');

// Default als Closure
$value = $request->session()->get('key', function () {
    return 'default';
});

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

### Existenz prüfen

```php theme={null}
// Vorhanden und nicht null
if ($request->session()->has('user_id')) {
    // ...
}

// Existiert, auch wenn null
if ($request->session()->exists('user_id')) {
    // ...
}

// Nicht vorhanden
if ($request->session()->missing('user_id')) {
    // ...
}
```

Beachten Sie den Unterschied:

| Methode  | Bei `null`      |
| -------- | --------------- |
| `has`    | Liefert `false` |
| `exists` | Liefert `true`  |

### Daten schreiben

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

// Via Helper
session(['user_name' => 'Tanaka']);

// In ein Array pushen
$request->session()->push('cart.items', ['id' => 1, 'name' => 'Produkt A']);
```

### Daten löschen

```php theme={null}
// Einen Schlüssel
$request->session()->forget('user_name');

// Mehrere
$request->session()->forget(['user_name', 'cart']);

// Alles
$request->session()->flush();
```

## Flash-Daten

Flash-Daten leben nur für den **nächsten Request**.
Ideal für einmalige Meldungen nach einer Formularübermittlung.

### Speichern mit `flash()`

```php theme={null}
$request->session()->flash('status', 'Beitrag gespeichert.');
```

Nach dem nächsten Request wird der Wert automatisch gelöscht.

### Flash-Daten verlängern

```php theme={null}
// Alle Flash-Daten um einen Request verlängern
$request->session()->reflash();

// Nur bestimmte Schlüssel
$request->session()->keep(['status', 'message']);
```

### Anzeige 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>
  Wenn Sie die Anzeige der Flash-Meldung in Ihrer Layout-Datei (`layouts/app.blade.php`) unterbringen, erscheint sie konsistent auf allen Seiten.
</Tip>

## Praxisbeispiel: Meldung nach Formularübermittlung

Nach dem Absenden eines Formulars legen Sie eine Erfolgsmeldung in die Session, redirecten und zeigen sie auf der Zielseite an – ein Klassiker.

<Steps>
  <Step title="Routen definieren">
    ```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="Controller implementieren">
    Nach dem Speichern wird mit Flash-Meldung umgeleitet.

    ```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', 'Beitrag erstellt.');
        }
    }
    ```

    `redirect()->with('success', '...')` ist eine Kurzform, um Flash-Daten mit einem Redirect zu übergeben.
  </Step>

  <Step title="Meldung im Layout anzeigen">
    ```blade theme={null}
    <!DOCTYPE html>
    <html>
    <head>
        <title>My App</title>
    </head>
    <body>
        {{-- Flash-Meldung --}}
        @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="Übersichts-View anlegen">
    ```blade theme={null}
    {{-- resources/views/posts/index.blade.php --}}

    @extends('layouts.app')

    @section('content')
    <h1>Beiträge</h1>

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

    Nach dem Speichern und Redirect erscheint einmalig „Beitrag erstellt." oben auf der Übersichtsseite.
  </Step>
</Steps>

### Kombination mit Validierungsfehlern

Bei fehlgeschlagener Validierung nutzen Sie `back()->withErrors()`.
Laravel legt die Fehler automatisch als Flash ab, sodass in Blade `$errors` verfügbar ist.

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

    Post::create($validated);

    // Erfolg: mit Flash weiterleiten
    return redirect()
        ->route('posts.index')
        ->with('success', 'Beitrag erstellt.');

    // Bei Validierungsfehler führt Laravel automatisch back()->withErrors()->withInput() aus
}
```

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

@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">Inhalt</label>
        <textarea id="body" name="body">{{ old('body') }}</textarea>
        @error('body')
            <span>{{ $message }}</span>
        @enderror
    </div>

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

<Warning>
  `flush()` löscht **alles** in der Session – auch den Login-Status. Für gezieltes Löschen einzelner Schlüssel nutzen Sie `forget()`.
</Warning>

## Nächste Schritte

<Card title="Validierung" icon="check-circle" href="/de/validation">
  Erfahren Sie, wie Sie Formulareingaben validieren.
</Card>


## Related topics

- [Session fortsetzen](/de/packages/laravel-copilot-sdk/resume.md)
- [Session-Hooks](/de/packages/laravel-copilot-sdk/hooks.md)
- [Cloud Sessions](/de/packages/laravel-copilot-sdk/cloud-sessions.md)
- [Remote Sessions](/de/packages/laravel-copilot-sdk/remote-sessions.md)
- [Session-Lebenszyklus-Ereignisse](/de/packages/laravel-copilot-sdk/session-lifecycle-event.md)
