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

# Sessioni

> Come usare le sessioni HTTP di Laravel per mantenere dati tra le richieste

## Cos'è una sessione

HTTP è un protocollo stateless. HTTP di per sé non ha meccanismi per mantenere le informazioni utente tra le richieste.
La sessione di Laravel offre un modo per mantenere i dati dell'utente attraverso più richieste.

Nella sessione salvi informazioni che vuoi mantenere tra le richieste: stato di login, articoli nel carrello, dati parziali di un form.

## Configurazione del driver di sessione

Le impostazioni della sessione sono in `config/session.php`.
Puoi cambiare il driver tramite la variabile d'ambiente `SESSION_DRIVER` (file `.env`).

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

I driver supportati di serie da Laravel sono:

| Driver     | Descrizione                                                     |
| ---------- | --------------------------------------------------------------- |
| `file`     | Salva come file in `storage/framework/sessions` (predefinito)   |
| `cookie`   | Salva come cookie cifrato nel browser                           |
| `database` | Salva in una tabella del database                               |
| `redis`    | Salva su Redis (veloce)                                         |
| `array`    | Salva in un array PHP (per test; non persiste tra le richieste) |

<Info>
  Nel progetto Laravel di default è configurato il driver `database`. Con `database` serve la tabella `sessions`, già inclusa nelle migration predefinite: puoi usarla così com'è.
</Info>

## Come accedere alla sessione

Puoi accedere alla sessione in due modi: tramite i metodi dell'istanza `Request` o tramite l'helper globale `session()`.

### Usando l'istanza Request

Ricevi `Request` come type hint nel metodo del controller e accedi con `$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]);
    }
}
```

### Usando l'helper globale `session()`

L'helper `session()` puoi chiamarlo da controller, viste o ovunque.

```php theme={null}
// Recupera un valore
$value = session('key');

// Recupera con valore predefinito
$value = session('key', 'default');

// Salva un valore
session(['key' => 'value']);
```

<Tip>
  In entrambi i casi puoi verificare nei test con `assertSessionHas`. Nei controller usare `$request->session()` rende esplicite le dipendenze.
</Tip>

## Operazioni sulla sessione

### Lettura dei dati

```php theme={null}
// Recupera specificando la chiave
$value = $request->session()->get('key');

// Con valore predefinito
$value = $request->session()->get('key', 'default');

// Con valore predefinito da closure
$value = $request->session()->get('key', function () {
    return 'default';
});

// Recupera tutti i dati di sessione
$data = $request->session()->all();
```

### Verifica dell'esistenza

```php theme={null}
// true se il valore esiste ed è diverso da null
if ($request->session()->has('user_id')) {
    // ...
}

// true anche se null, purché la chiave esista
if ($request->session()->exists('user_id')) {
    // ...
}

// true se non esiste
if ($request->session()->missing('user_id')) {
    // ...
}
```

Fai attenzione alla differenza tra `has` ed `exists`.

| Metodo   | Se il valore è `null` |
| -------- | --------------------- |
| `has`    | Restituisce `false`   |
| `exists` | Restituisce `true`    |

### Scrittura dei dati

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

// Tramite helper globale
session(['user_name' => 'Rossi']);

// Aggiunta a un array
$request->session()->push('cart.items', ['id' => 1, 'name' => 'Prodotto A']);
```

### Rimozione dei dati

```php theme={null}
// Rimuove una chiave specifica
$request->session()->forget('user_name');

// Rimuove più chiavi insieme
$request->session()->forget(['user_name', 'cart']);

// Rimuove tutti i dati di sessione
$request->session()->flush();
```

## Dati flash

I dati flash sono dati di sessione validi **solo per la richiesta successiva**.
Sono adatti a informazioni da mostrare una sola volta, come un messaggio di successo o un errore di form.

### Salvare dati con `flash()`

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

Puoi leggere il dato nella richiesta successiva; dopodiché viene rimosso automaticamente.

### Estendere i dati flash

```php theme={null}
// Estende tutti i dati flash di un'altra richiesta
$request->session()->reflash();

// Estende solo chiavi specifiche
$request->session()->keep(['status', 'message']);
```

### Mostrare messaggi flash 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>
  Metti la visualizzazione dei messaggi flash nel file di layout (come `layouts/app.blade.php`): compariranno in modo uniforme su tutte le pagine.
</Tip>

## Esempio pratico: messaggi dopo l'invio di un form

Salvare un messaggio di successo in sessione e reindirizzare per mostrarlo nella pagina successiva è un pattern classico delle app web.

<Steps>
  <Step title="Definizione delle route">
    ```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="Implementazione del controller">
    Nel metodo `store` che riceve il form, dopo il salvataggio reindirizza con un messaggio di successo.

    ```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', 'Post creato.');
        }
    }
    ```

    `redirect()->with('success', '...')` è la scorciatoia per passare dati flash alla destinazione del redirect.
  </Step>

  <Step title="Mostra il messaggio nel layout">
    Aggiungi la parte di visualizzazione dei messaggi flash a `resources/views/layouts/app.blade.php`.

    ```blade theme={null}
    <!DOCTYPE html>
    <html>
    <head>
        <title>My App</title>
    </head>
    <body>
        {{-- Messaggi flash --}}
        @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="Crea la vista dell'elenco">
    ```blade theme={null}
    {{-- resources/views/posts/index.blade.php --}}

    @extends('layouts.app')

    @section('content')
    <h1>Elenco dei post</h1>

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

    Dopo il salvataggio e il redirect, in cima all'elenco compare una sola volta il messaggio "Post creato.".
  </Step>
</Steps>

### Pattern combinato con errori di validazione

In caso di validazione fallita si combina `back()->withErrors()`.
Laravel salva automaticamente gli errori come dati flash, così in Blade puoi usare la variabile `$errors`.

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

    Post::create($validated);

    // Successo: redirect con messaggio flash
    return redirect()
        ->route('posts.index')
        ->with('success', 'Post creato.');

    // In caso di validazione fallita Laravel esegue automaticamente back()->withErrors()->withInput()
}
```

```blade theme={null}
{{-- Pagina del form --}}

@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">Titolo</label>
        <input
            id="title"
            type="text"
            name="title"
            value="{{ old('title') }}"
        />
        @error('title')
            <span>{{ $message }}</span>
        @enderror
    </div>

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

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

<Warning>
  `flush()` elimina tutti i dati di sessione, incluso lo stato di login. Se vuoi eliminare solo i dati utente, usa `forget()` indicando le chiavi specifiche.
</Warning>

## Prossimi passi

<Card title="Validazione" icon="check-circle" href="/it/validation">
  Rivedi come validare i dati di input dei form.
</Card>


## Related topics

- [Guida all'aggiornamento da Laravel 12 a 13](/it/blog/upgrade-12-to-13.md)
- [Contesto e filtraggio della sessione](/it/packages/laravel-copilot-sdk/session-context.md)
- [Cloud Sessions](/it/packages/laravel-copilot-sdk/cloud-sessions.md)
- [Redis](/it/redis.md)
- [Introduzione - GitHub Copilot SDK for Laravel](/it/packages/laravel-copilot-sdk/getting-started.md)
