Ritorna alla lista completa degli articoli

Mettiti alla prova: utilizzo dei cookies

PHP - SFIDE - gennaio 22, 2022

L'utilizzo dei cookies, a seconda del grado di specificità, permette all'utente di essere identificato quando naviga o utilizza un sito web. I cookies vengono memorizzati nel browser dell'utente. Con i cookies l'utente è agevolato in alcune operazioni che utilizza maggiormente di più. Sono esempi, di utilizzo dei cookies, le preferenze o le impostazioni di un sito web, la schermata di accesso o login ad un area riservata, l'accettazione della privacy, l'invio di un modulo e tanto altro.

Per finalità legate all'esercizio, utilizzeremo i cookies ai fini del completamento di un modulo o form. Immaginate un questionario molto lungo e complesso, con tanti campi da completare e suddiviso probabilmente in più step. Ci sono varie soluzioni che è possibile adottare, tra queste, quella dei cookies. Bisogna prevedere, ad esempio, che l'utente possa decidere di completare il modulo senza inviarlo per dargli l'opportunità di modificarlo in un secondo momento. Si presuppone che l'utente, una volta inviato il modulo, non può più modificarlo. Nell'esercizio la validità dei cookies è fissata a 15 giorni. Il vantaggio nell'utilizzo dei cookies è un minor consumo delle risorse lato server, grazie ad un minor numero di connessioni al database nel reperire le informazioni ma di contro anche una potenziale perdita dei dati compilati dall'utente. Esistono infatti molte estensioni che alla chiusura del browser fanno una pulizia di tutti i cookies utilizzati durante la navigazione web. Quindi prima di utilizzarli e bene capire i vantaggi e svantaggi.

L'esercizio che tratteremo, comprende un modulo dati già usato per un'altra esercitazione che trovate qui. In questo caso, ci concentreremo sul come memorizzare i cookies, eliminarli tramite un apposito collegamento e verificare che i dati rimangano memorizzati anche dopo la chiusura del browser o ricaricando la pagina del form, ipotizzando:

  1. che l'utente voglia ritornarci in un secondo momento per confermare l'invio del modulo;
  2. che l'utente abbia cliccato sul pulsante "salva come bozza" per consentire il salvataggio dei dati e quindi dei cookies;
  3. che l'utente sia se clicca sul link "elimina tutti i cookies" o sul pulsante "conferma e invia", eliminerà tutti i cookies in quanto non più necessari;

Per completezza, questo esercizio, punta a memorizzare anche informazioni più complesse come gli array. 

Iniziamo. Copiate il codice della pagina start.php e provate a testarlo. Compilate i campi obbligatori. Una volta finito cliccate sul pulsante "salva come bozza" e poi ricaricate la pagina (potete anche chiudere o riaprire la pagina nel browser), noterete che non tutti i cookies vengono memorizzati soprattutto i campi trattati come array ed è li che dovrete inserire il codice necessario affinché i cookies funzionino correttamente. 

start.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Questionario</title>

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
</head>

<body>

    <?php

    // Costanti
    define("CONST_ERROR",'error');
    define("CONST_COMPLETATO",'completato');
    define("CONST_OBBLIGATORIO",'obbligatorio');
    define("CONST_FORMATO_NON_VALIDO",'formato non valido');
    define("CONST_PASSWORD_TROPPO_CORTA",'Password troppo corta!');
    define("CONST_PASSWORD_ALMENO_UN_NUMERO",'La password deve includere almeno un numero!');
    define("CONST_PASSWORD_ALMENO_UNA_LETTERA",'la password deve includere almeno una lettera!');

    // Funzioni
    function redirect($page,$msg){
        header("location:" . $page . '?msg=' . $msg);
        exit();
    }

    function display_error_msg($msg)
    {
        $error = !(empty($msg)) ? '<div class="text-danger fw-bold"><i class="bi bi-exclamation-circle-fill"></i> ' . $msg . '</div>' : '';

        return $error;
    }

    function display_valid_msg($msg)
    {
        $valid = !(empty($msg)) ? '<div class="text-success fw-bold"><i class="bi bi-check-circle-fill"></i> ' . $msg . '</div>' : '';
        return $valid;
    }

    function required_field($field, $msg = true)
    {
        if ($msg == true) {
            $field = !empty($field) ? display_valid_msg(CONST_COMPLETATO) : display_error_msg(CONST_OBBLIGATORIO);
        } else {
            $field = !empty($field) ? $field : CONST_ERROR;
        }

        return $field;
    }

    function required_email($email, $msg = true)
    {
        $res = '';
        if ($msg == true) {
            $res = !empty($email) ? '' : display_error_msg(CONST_OBBLIGATORIO);
            $res .= filter_var($email, FILTER_VALIDATE_EMAIL) ? display_valid_msg(CONST_COMPLETATO) : display_error_msg(CONST_FORMATO_NON_VALIDO);
        } else {
            $res = !empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL) ? $email : CONST_ERROR;
        }

        return $res;
    }

    function required_password($pwd, $msg = true)
    {
        $errore = '';

        if (strlen($pwd) < 8) {
            $errore .= display_error_msg(CONST_PASSWORD_TROPPO_CORTA);
        }

        if (!preg_match("#[0-9]+#", $pwd)) {
            $errore .= display_error_msg(CONST_PASSWORD_ALMENO_UN_NUMERO);
        }

        if (!preg_match("#[a-zA-Z]+#", $pwd)) {
            $errore .= display_error_msg(CONST_PASSWORD_ALMENO_UNA_LETTERA);
        }

        if ($msg == true) {
            return empty($errore) ? display_valid_msg(CONST_COMPLETATO) : $errore;
        } else {
            return empty($errore) ? '' : CONST_ERROR;
        }
    }

    function delete_cookies()
    {
        // da completare
        $time = time() - 3600;
        $path = "/";
    }

    function setcookie_for_array($name, $value, $time, $path)
    {
        // da completare
    }

    function get_msg_alert($str_msg)
    {
        $msg = '<div class="container">';
        $msg .= '<div class="row">';
        $msg .= '<div class="col-12 mt-4">';
        $msg .= '<div class="alert alert-dismissible alert-warning">';
        $msg .= '<button type="button" class="btn-close" data-bs-dismiss="alert"></button>';
        $msg .= '<h4 class="alert-heading">Avviso!</h4>';
        $msg .= '<p>' . $str_msg . '</p>';
        $msg .= '</div>';
        $msg .= '</div>';
        $msg .= '</div>';
        $msg .= '</div>';

        return $msg;
    }

    // Campi obbligatori
    // Verifico se sono stati gia compilati
    $form_email = isset($_COOKIE["form_email"]) ? $_COOKIE["form_email"] : "";
    $form_password = isset($_COOKIE["form_password"]) ? $_COOKIE["form_password"] : "";
    $form_titolo_studio = isset($_COOKIE["form_titolo_studio"]) ? $_COOKIE["form_titolo_studio"] : "";
    $form_films_preferiti = isset($_COOKIE["form_films_preferiti"]) ? $_COOKIE["form_films_preferiti"] : array();
    $form_sesso = isset($_COOKIE["form_sesso"]) ? $_COOKIE["form_sesso"] : array();
    $form_hobby = isset($_COOKIE["form_hobby"]) ? $_COOKIE["form_hobby"] : array();

    // Visualizzo il messaggio di avviso in caso di completamento del campo
    $required_email = !empty($form_email) ? required_email($form_email) : "";
    $required_password = !empty($form_password) ? required_password($form_password) : "";
    $required_titolo_studio = !empty($form_titolo_studio) ? required_field($form_titolo_studio) : "";
    $required_films_preferiti = !empty($form_films_preferiti) ? required_field($form_films_preferiti) : "";
    $required_sesso = !empty($form_sesso) ? required_field($form_sesso) : "";
    $required_hobby = !empty($form_hobby) ? required_field($form_hobby) : "";

    // Campi non obbligatori
    $form_marketing = isset($_COOKIE["form_marketing"]) ? $_COOKIE["form_marketing"] : array();
    $form_gradimento = isset($_COOKIE["form_gradimento"]) ? $_COOKIE["form_gradimento"] : 0;
    $form_note = isset($_COOKIE["form_note"]) ? $_COOKIE["form_note"] : "";

    if ($_SERVER["REQUEST_METHOD"] == "GET") {

        // Elimino i cookies
        $elimina_cookies = isset($_GET["elimina_cookies"]) ? $_GET["elimina_cookies"] : "false";
        if ($elimina_cookies == "true") {
            delete_cookies();
            redirect($_SERVER['PHP_SELF'],"Cookies eliminati correttamente");
        }

        // Visualizzo l'esito della richiesta
        if (isset($_GET["msg"]) ) {
            $msg = get_msg_alert($_GET["msg"]);
            echo $msg;
        }
    }

    // POST
    if ($_SERVER["REQUEST_METHOD"] == "POST") {

        // Variabili del form
        $form_email = $_POST["form_email"];
        $form_password = $_POST["form_password"];
        $form_titolo_studio = $_POST["form_titolo_studio"];

        $form_films_preferiti = !empty($_POST["form_films_preferiti"]) ? $_POST["form_films_preferiti"] : array();
        $form_sesso = !empty($_POST["form_sesso"]) ? $_POST["form_sesso"] : array();
        $form_hobby = !empty($_POST["form_hobby"]) ? $_POST["form_hobby"] : array();
        $form_marketing = !empty($_POST["form_marketing"]) ? $_POST["form_marketing"] : array();

        $form_gradimento = $_POST["form_gradimento"];
        $form_note = $_POST["form_note"];

        // Verifica dei campi obbligatori
        $required_email = required_email($form_email);
        $required_password = required_password($form_password);
        $required_titolo_studio = required_field($form_titolo_studio);
        $required_films_preferiti = required_field($form_films_preferiti);
        $required_sesso = required_field($form_sesso);
        $required_hobby = required_field($form_hobby);


        // Invio del form - salva come bozza
        if ($_REQUEST['btn_submit'] == "salva_come_bozza") {

            // Imposto i cookie a 15 giorni
            $time = time() + (3600 * 24 * 15);
            $path = "/";

            setcookie("form_email", $form_email, $time, $path);
            setcookie("form_password", $form_password, $time, $path);
            setcookie("form_titolo_studio", $form_titolo_studio, $time, $path);

            setcookie_for_array("form_films_preferiti", $form_films_preferiti, $time, $path);
            setcookie_for_array("form_sesso", $form_sesso, $time, $path);
            setcookie_for_array("form_hobby", $form_hobby, $time, $path);
            setcookie_for_array("form_marketing", $form_marketing, $time, $path);

            setcookie("form_gradimento", $form_gradimento, $time, $path);
            setcookie("form_note", $form_note, $time, $path);

            $_COOKIE["form_email"] = $form_email;
            $_COOKIE["form_password"] = $form_password;

            $_COOKIE["form_titolo_studio"] = $form_titolo_studio;
            $_COOKIE["form_films_preferiti"] = $form_films_preferiti;
            $_COOKIE["form_sesso"] = $form_sesso;
            $_COOKIE["form_hobby"] = $form_hobby;
            $_COOKIE["form_marketing"] = $form_marketing;

            $_COOKIE["form_gradimento"] = $form_gradimento;
            $_COOKIE["form_note"] = $form_note;
        }

        // Invio del form - conferma e invia
        if ($_REQUEST['btn_submit'] == "conferma_e_invia") {
            if (
                required_email($form_email, false) == CONST_ERROR ||
                required_password($form_password, false) == CONST_ERROR ||
                required_field($form_titolo_studio, false) == CONST_ERROR ||
                required_field($form_films_preferiti, false) == CONST_ERROR ||
                required_field($form_sesso, false) == CONST_ERROR ||
                required_field($form_hobby, false) == CONST_ERROR
            ) {
                $msg = get_msg_alert("Si prega di completare i campi obbligatori. Grazie.");
                echo $msg;
            } else {
                // Elimino i cookie una volta inviata la domanda
                delete_cookies();

                redirect($_SERVER['PHP_SELF'],'Grazie per aver completato il questionario.');
            }
        }
    }

    ?>

    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="py-5 text-center">
                    <h2>Questionario</h2>
                    <p class="lead">Utilizzo dei cookie per mantenere i dati in un modulo</p>
                </div>

                <!-- riepilogo in formato dump dei dati inviati in caso di invio -->
                <?php echo !(empty($_POST)) ? "<pre>" . var_dump($_POST) . "</pre>" : ""; ?>

                <form id="form" name="form" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">

                    <fieldset>
                        <legend>Campi obbligatori</legend>
                        <div class="row">
                            <div class="form-group col-md-6 mb-3">
                                <label for="form_email">Email</label>
                                <input type="text" class="form-control" id="form_email" name="form_email" aria-describedby="email" placeholder="Email..." value="<?php echo $form_email; ?>">
                                <small class="form-text text-muted">Non condividere la tua email.</small>
                                <?php echo $required_email; ?>
                            </div>
                            <div class="form-group col-md-6 mb-3">
                                <label for="form_password">Password</label>
                                <input type="password" class="form-control" id="form_password" name="form_password" placeholder="Password..." value="<?php echo $form_password; ?>">
                                <small class="form-text text-muted">Non condividere mai la tua password.</small>
                                <?php echo $required_password; ?>
                            </div>
                        </div>

                        <div class="row">
                            <div class="form-group col-md-3 mb-3">
                                <label for="form_titolo_studio">Titolo di studio</label>
                                <select class="form-select" id="form_titolo_studio" name="form_titolo_studio">
                                    <option <?php echo $form_titolo_studio == "" ? "selected" : ""; ?> value="">Selezionare</option>
                                    <option <?php echo $form_titolo_studio == "diploma" ? "selected" : ""; ?> value="diploma">Diploma</option>
                                    <option <?php echo $form_titolo_studio == "laurea" ? "selected" : ""; ?> value="laurea">Laurea</option>
                                    <option <?php echo $form_titolo_studio == "specialistica" ? "selected" : ""; ?> value="specialistica">Specialistica</option>
                                </select>
                                <?php echo $required_titolo_studio; ?>
                            </div>
                            <div class="form-group col-md-3 mb-3">
                                <label for="form_films_preferiti">Film preferiti</label>
                                <select multiple="multiple" class="form-select" id="form_films_preferiti" name="form_films_preferiti[]">
                                    <option <?php echo in_array("spiderman", $form_films_preferiti) ? "selected" : ""; ?> value="spiderman">Spiderman</option>
                                    <option <?php echo in_array("matrix", $form_films_preferiti) ? "selected" : ""; ?> value="matrix">Matrix</option>
                                    <option <?php echo in_array("alice_paese_meraviglie", $form_films_preferiti) ? "selected" : ""; ?> value="alice_paese_meraviglie">Alice nel paese delle meraviglie</option>
                                    <option <?php echo in_array("la_bugia", $form_films_preferiti) ? "selected" : ""; ?> value="la_bugia">La bugia</option>
                                    <option <?php echo in_array("terminator", $form_films_preferiti) ? "selected" : ""; ?> value="terminator">Terminator</option>
                                </select>
                                <div class="form-text text-muted">Premi CTRL per selezionarne di più</div>
                                <?php echo $required_films_preferiti; ?>
                            </div>
                            <div class="form-group col-md-3 mb-3">
                                <label class="form-label">Sesso</label>
                                <div class="form-check">
                                    <label class="form-check-label">
                                        <input type="radio" class="form-check-input" name="form_sesso[]" id="maschio" value="maschio" <?php echo in_array("maschio", $form_sesso) ? 'checked' : ''; ?>>
                                        Maschio
                                    </label>
                                </div>
                                <div class="form-check">
                                    <label class="form-check-label">
                                        <input type="radio" class="form-check-input" name="form_sesso[]" id="femmina" value="femmina" <?php echo in_array("femmina", $form_sesso) ? 'checked' : ''; ?>>
                                        Femmina
                                    </label>
                                </div>
                                <?php echo $required_sesso; ?>
                            </div>


                            <div class="form-group col-md-3 mb-3">
                                <label class="form-label">I tuoi hobby preferiti</label>
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" value="calcio" id="form_calcio" name="form_hobby[]" <?php echo in_array("calcio", $form_hobby) ? 'checked' : ''; ?>>
                                    <label class="form-check-label" for="form_calcio">
                                        Calcio
                                    </label>
                                </div>
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" value="tennis" id="form_tennis" name="form_hobby[]" <?php echo in_array("tennis", $form_hobby) ? 'checked' : ''; ?>>
                                    <label class="form-check-label" for="form_tennis">
                                        Tennis
                                    </label>
                                </div>
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" value="nuoto" id="form_nuoto" name="form_hobby[]" <?php echo in_array("nuoto", $form_hobby) ? 'checked' : ''; ?>>
                                    <label class="form-check-label" for="form_nuoto">
                                        Nuoto
                                    </label>
                                </div>
                                <?php echo $required_hobby; ?>
                            </div>
                        </div>
                    </fieldset>

                    <fieldset>
                        <legend>Campi facoltativi</legend>
                        <div class="row">

                            <div class="form-group col-md-6 mb-3">
                                <label class="form-label">Marketing</label>
                                <div class="form-check form-switch">
                                    <input class="form-check-input" type="checkbox" id="form_invio_email_promozionali" name="form_marketing[]" value="invio_email_promozionali" <?php echo in_array("invio_email_promozionali", $form_marketing) ? 'checked' : ''; ?>>
                                    <label class="form-check-label" for="form_invio_email_promozionali">Mandami email promozionali</label>
                                </div>
                                <div class="form-check form-switch">
                                    <input class="form-check-input" type="checkbox" id="form_contattami_per_altri_questionari" name="form_marketing[]" value="contattami_per_altri_questionari" <?php echo in_array("contattami_per_altri_questionari", $form_marketing) ? 'checked' : ''; ?>>
                                    <label class="form-check-label" for="form_contattami_per_altri_questionari">Contattami per altri questionari</label>
                                </div>
                            </div>
                            <div class="form-group col-md-6">
                                <label for="form_gradimento" class="form-label">Gradimento del questionario da zero a 100</label>
                                <input type="range" class="form-range" min="0" max="100" step="1" id="form_gradimento" name="form_gradimento" value="<?php echo $form_gradimento; ?>">
                            </div>

                        </div>

                        <div class="row">
                            <div class="form-group col-md-12 mb-3">
                                <label for="form_note">Note</label>
                                <textarea class="form-control" id="form_note" name="form_note" rows="3"><?php echo $form_note; ?></textarea>
                            </div>
                        </div>

                        <div class="mb-3">
                            <div class="row">
                                <div class="col-6 d-grid">
                                    <button type="submit" name="btn_submit" value="conferma_e_invia" class="btn btn-success">Conferma e invia</button>
                                    <div class="form-text">Una volta inviata la domanda non potrai più modificarla</div>
                                </div>
                                <div class="col-6 d-grid">
                                    <button type="submit" name="btn_submit" value="salva_come_bozza" class="btn btn-secondary">Salva come bozza</button>
                                    <div class="form-text">I dati rimmarrano memorizzati sul tuo dispositivo per 15 giorni</div>
                                </div>
                            </div>
                        </div>

                    </fieldset>

                </form>

                <a href="<?php echo $_SERVER['PHP_SELF'] . '?elimina_cookies=true'; ?>">Elimina tutti i cookie</a>
            </div>
        </div>
    </div>


    <!-- Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>

</html>

Le due funzioni da completare sono:

  • delete_cookies()
  • setcookie_for_array()

La funzione delete_cookies() si occupa di eliminare tutti i cookies. Nel form è presente un collegamento dove l'utente, una volta che avrà cliccato su di esso, andrà ad eliminare tutte le informazioni memorizzate. In fase di test o debug è molto utile per lo sviluppatore verificare se i cookies vengono creati ed eliminati correttamente. Potete anche usare la console per gli sviluppatori presente nei vari browser. Utilizzando ad esempio Microsoft Edge i cookies vengono memorizzati nella sezione applicazione come da immagine:

Dove vengono memorizzati i cookies in Microsoft Edge

Quindi ad esempio nella funzione delete_cookies() comincerò ad eliminare il cookie che permette di identificare l'email attraverso l'apposito codice:

$time = time() - 3600;
$path = "/";

if (isset($_COOKIE["form_email"])) {
      setcookie("form_email", "", $time, $path);
}

In PHP non c'è una funzione incorporata che permetta di eliminare in maniera diretta un cookie. Dobbiamo ricorrere ad un artifizio. Il codice non fa altro che impostare il cookie con una data di scadenza inferiore alla data attuale rendendolo invalido. Lo stesso codice può essere applicato agli altri campi di testo ad eccezione di quelli che sono trattati come array che in questo esercizio sono gli hobby, il sesso, i film preferiti e le preferenze marketing. Li dovrete mostrare la vostra abilità apportando le modifiche necessarie al codice.

Per quanto riguarda la funzione setcookie_for_array() dobbiamo settare uno o più cookie in base alle scelte compiute dall'utente. Quindi se l'utente ad esempio sceglierà più di un film dovremo impostare un cookie per ogni preferenza. In questo caso la funzione setcookie() di PHP dovrà comprendere un indice per ogni elemento del vettore:

setcookie('mio_array[0]', 'valore 0' , $time, $path);
setcookie('mio_array[1]', 'valore 1' , $time, $path);
setcookie('mio_array[2]', 'valore 2' , $time, $path);

Questo esercizio si concentra sull'utilizzo dei cookies. A livello di sicurezza non è raccomandabile memorizzare dati sensibili, come potrebbe essere una password, attraverso i cookies che siano in chiaro e non criptati.

Nell'immagine in allegato è presente il risultato finale. Una volta chiuso e riaperto il browser dovreste vedere tutti i dati precedentemente compilati a patto che l'utente abbia cliccato sul pulsante "salva come bozza".

Buon lavoro e soprattutto divertitevi :)

Attenzione!

E' disponibile del contenuto riservato.
Devi essere registrato per poterlo visionare

Accedi o registrati
Mettiti alla prova: utilizzo dei cookies
Mettiti alla prova: utilizzo dei cookies