PHP e Cookie: creare un sistema di “ricordami” per il carrello

by theArchitect
SHARE
PHP e Cookie: creare un sistema di “ricordami” per il carrello
© Guida-HTML5.it

Introduzione

Quando si parla di cookie in PHP, il pensiero va spesso al login automatico o alle preferenze utente. Un uso molto pratico, però, è la persistenza del carrello: salvare nel browser dell’utente alcuni dati temporanei, come gli ID dei prodotti aggiunti, in modo che il carrello non si svuoti alla chiusura del browser o al ritorno sul sito dopo qualche ora o giorno.

Questo approccio è utile soprattutto nei siti e-commerce piccoli o medi, nei prototipi, oppure come supporto a una persistenza lato server già esistente. Ovviamente non è la soluzione ideale per dati sensibili o per carrelli complessi con quantità, prezzi dinamici e promozioni: in quei casi è meglio salvare tutto nel database o in sessioni server-side. Tuttavia, sapere come gestire un carrello persistente con i cookie è un’abilità molto utile per chi sviluppa in PHP.

In questo tutorial vedremo come:

  • salvare nel cookie una lista di prodotti;
  • recuperare i dati al caricamento della pagina;
  • aggiornare il cookie quando l’utente aggiunge o rimuove articoli;
  • gestire la scadenza e la pulizia dei dati;
  • applicare alcune best practice importanti.

Codice completo

Nel seguente esempio usiamo un carrello molto semplice: memorizziamo nel cookie solo un array di ID prodotto e quantità. Il catalogo viene simulato con un array PHP, ma in un progetto reale arriverebbe dal database.

<?php
// catalogo di esempio
$catalogo = [
    101 => [´nome´ => ´T-shirt Basic´, ´prezzo´ => 19.90],
    102 => [´nome´ => ´Felpa Hoodie´, ´prezzo´ => 39.90],
    103 => [´nome´ => ´Cappellino Logo´, ´prezzo´ => 14.50],
];

// nome del cookie del carrello
$cookieName = ´cart_items´;

// recupero del carrello dal cookie
$carrello = [];

if (isset($_COOKIE[$cookieName])) {
    $decoded = json_decode($_COOKIE[$cookieName], true);

    if (is_array($decoded)) {
        $carrello = $decoded;
    }
}

// aggiunta prodotto al carrello
if (isset($_GET[´add´])) {
    $idProdotto = (int) $_GET[´add´];

    if (isset($catalogo[$idProdotto])) {
        if (!isset($carrello[$idProdotto])) {
            $carrello[$idProdotto] = 0;
        }

        $carrello[$idProdotto]++;

        // salva il carrello nel cookie per 7 giorni
        setcookie(
            $cookieName,
            json_encode($carrello),
            [
                ´expires´ => time() + 7 * 24 * 60 * 60,
                ´path´ => ´/´,
                ´httponly´ => true,
                ´samesite´ => ´Lax´,
                ´secure´ => isset($_SERVER[´HTTPS´]) && $_SERVER[´HTTPS´] === ´on´
            ]
        );

        // aggiorna anche la variabile locale per questa richiesta
        $_COOKIE[$cookieName] = json_encode($carrello);
    }
}

// rimozione prodotto dal carrello
if (isset($_GET[´remove´])) {
    $idProdotto = (int) $_GET[´remove´];

    if (isset($carrello[$idProdotto])) {
        unset($carrello[$idProdotto]);

        setcookie(
            $cookieName,
            json_encode($carrello),
            [
                ´expires´ => time() + 7 * 24 * 60 * 60,
                ´path´ => ´/´,
                ´httponly´ => true,
                ´samesite´ => ´Lax´,
                ´secure´ => isset($_SERVER[´HTTPS´]) && $_SERVER[´HTTPS´] === ´on´
            ]
        );

        $_COOKIE[$cookieName] = json_encode($carrello);
    }
}

// calcolo totale
$totale = 0.0;
?>

<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Carrello persistente con cookie</title>
</head>
<body>

<h1>Carrello persistente</h1>

<h2>Prodotti disponibili</h2>
<ul>
    <?php foreach ($catalogo as $id => $prodotto): ?>
        <li>
            <strong><?php echo htmlspecialchars($prodotto[´nome´]); ?></strong>
            - €<?php echo number_format($prodotto[´prezzo´], 2, ´,´, ´.´); ?>
            <a href="?add=<?php echo $id; ?>">Aggiungi al carrello</a>
        </li>
    <?php endforeach; ?>
</ul>

<h2>Il tuo carrello</h2>

<?php if (empty($carrello)): ?>
    <p>Il carrello è vuoto.</p>
<?php else: ?>
    <ul>
        <?php foreach ($carrello as $id => $quantita): ?>
            <?php if (isset($catalogo[$id])): 
                $subtotale = $catalogo[$id][´prezzo´] * $quantita;
                $totale += $subtotale;
            ?>
                <li>
                    <strong><?php echo htmlspecialchars($catalogo[$id][´nome´]); ?></strong>
                    - Quantità: <?php echo (int) $quantita; ?>
                    - Subtotale: €<?php echo number_format($subtotale, 2, ´,´, ´.´); ?>
                    <a href="?remove=<?php echo $id; ?>">Rimuovi</a>
                </li>
            <?php endif; ?>
        <?php endforeach; ?>
    </ul>

    <p><strong>Totale:</strong> €<?php echo number_format($totale, 2, ´,´, ´.´); ?></p>
<?php endif; ?>

</body>
</html>

Spiegazione

Vediamo il funzionamento del codice in modo ordinato.

1. Lettura del cookie

All’inizio controlliamo se esiste il cookie cart_items. Se è presente, lo decodifichiamo con json_decode(). Usiamo JSON perché è leggibile, semplice da salvare e comodo da trasformare in array PHP.

È importante verificare che il risultato di json_decode() sia davvero un array. Un cookie danneggiato, manipolato o scaduto può contenere dati non validi.

2. Aggiunta di un prodotto

Quando l’utente clicca su un link come ?add=101, il codice controlla che il prodotto esista nel catalogo. Se sì, incrementa la quantità nel carrello. Questo permette di gestire più acquisti dello stesso articolo.

Dopo l’aggiornamento, il carrello viene risalvato nel cookie con setcookie(). In questo esempio il cookie dura 7 giorni.

3. Rimozione di un prodotto

Se l’utente clicca su ?remove=101, il prodotto viene eliminato dall’array e il cookie viene aggiornato. È una buona pratica riscrivere il cookie ogni volta che cambia lo stato del carrello.

4. Opzioni di sicurezza

Nel parametro di configurazione di setcookie() abbiamo incluso:

  • httponly: impedisce l’accesso al cookie da JavaScript;
  • samesite: riduce il rischio di invii cross-site indesiderati;
  • secure: invia il cookie solo su HTTPS.

Queste opzioni non rendono il cookie “sicuro” in assoluto, ma migliorano molto la protezione rispetto a un cookie lasciato con impostazioni base.

5. Generazione della vista

Infine, il codice mostra il catalogo e il carrello. Per ogni prodotto nel carrello, calcoliamo il subtotale e poi il totale finale. In una vera applicazione, il prezzo dovrebbe essere sempre ricalcolato dal server e non letto dal cookie, perché il cliente può modificarlo facilmente.

Best practice

L’uso dei cookie per la persistenza del carrello è comodo, ma va fatto con attenzione. Ecco le regole più importanti.

  • Non salvare dati sensibili nel cookie: mai password, token di pagamento o informazioni personali non necessarie.
  • Salva solo riferimenti: meglio memorizzare ID prodotto e quantità, non il prezzo finale.
  • Valida sempre i dati letti: un cookie può essere alterato dall’utente.
  • Usa HTTPS: il flag secure ha senso solo su connessioni protette.
  • Imposta una scadenza ragionevole: evitare cookie troppo lunghi se non servono davvero.
  • Non superare i limiti di dimensione: i cookie sono piccoli, quindi non usarli per strutture troppo grandi.
  • Sincronizza con il server quando possibile: per e-commerce reali, il cookie dovrebbe essere solo un supporto, non l’unica fonte di verità.

Un altro aspetto fondamentale è la gestione dei casi limite. Per esempio, se un prodotto non esiste più nel catalogo, il carrello deve ignorarlo o rimuoverlo. Se il cookie è corrotto, il sistema deve ricominciare da un carrello vuoto senza generare errori visibili all’utente.

Infine, ricorda che setcookie() deve essere chiamato prima di qualsiasi output HTML. Se stampi contenuto a schermo troppo presto, PHP non potrà più inviare gli header necessari per impostare il cookie.

Riepilogo

In questo tutorial abbiamo visto come usare i cookie in PHP per creare un sistema semplice di persistenza del carrello. L’idea è salvare nel browser solo i dati essenziali, come ID prodotto e quantità, e ricostruire il carrello al caricamento della pagina.

I punti chiave da ricordare sono:

  • leggere il cookie con $_COOKIE;
  • convertire i dati in un formato sicuro e gestibile, come JSON;
  • aggiornare il cookie con setcookie() ogni volta che il carrello cambia;
  • proteggere il cookie con opzioni come httponly, secure e samesite;
  • non considerare mai il cookie come fonte affidabile per dati critici.

Questo approccio è perfetto per imparare i fondamenti della persistenza lato client e per costruire funzionalità pratiche e leggere. In un progetto professionale, potrai poi evolverlo integrando database, sessioni e autenticazione utente.

Approfondisci con risorse ufficiali

  • PHP Manual - setcookie(): documentazione ufficiale sulla creazione e gestione dei cookie.
  • PHP Manual - $_COOKIE: superglobale per leggere i cookie inviati dal browser.
  • PHP Manual - json_encode() e json_decode(): utili per serializzare e deserializzare i dati del carrello.
  • MDN Web Docs - Cookies: ottima panoramica lato browser su comportamento, limiti e attributi dei cookie.
  • OWASP Session Management Cheat Sheet: utile per capire differenze tra cookie, sessioni e aspetti di sicurezza.

SHARE