Lezione Precedente
Lezione Successiva

Laboratorio di Sistemi Informativi

Validazione dei dati

Veniamo ad una problematica tipica delle applicazioni sulle basi di dati: la validazione dei dati inseriti. Si tratta di fare in modo che le operazioni richieste dall'utente non violino i vincoli di integrità imposti sulla base di dati. Ad esempio, nel caso della procedura di inserimento di nuovi voli, sarebbe preferibile che il sistema si rifiutasse di inserire un volo quando o il codice o il codice aeroporto partenza/destinazione non corrisponda ad un dato effettivamentre presente nel database (è un cosidetto "vincolo di chiave esterna")

Ci sono tre possibili ambienti in cui effettuare la validazione dei dati in una architettura a tre livelli:
  1. nel server database
  2. nel server applicativo (il server web nel nostro caso)
  3. nel client (il browser)
La validazione all'interno del browser fa sì che i dati non vengano neanche spediti al server web. Ad esempio, se l'utente immette una stringa dove il sistema si aspetta un numero, è possibile far sì che il browser si accorga di questo fatto e richieda all'utente di reimmettere i dati. La validazione lato client richiede l'utilizzo del linguaggio Javascript. Notare che la validazione lato client non è sicura!! L'utente può sempre disattivare Javascript e quindi aggirare (volente o nolente) i controlli.

Quando la validazione dati è eseguita sul server web, il programma che gestisce l'applicazione (i vari script PHP nel nostro caso) effettuano dei controlli prima di effetturare eventuali modifiche nella base di dati. La modifica viene effettuata solo se il controllo ha successo, altrimenti si visualizza un appropriato messaggio di errore.

Infine, si può relegare tutto al DBMS: questo può controllare la validità dei vincoli di chiavi esterna, o anche vincoli più complessi qualora questi siano supportati.  Tuttavia un approccio di questo tipo è poco efficiente (i dati devono viaggiare dal client fino al server DBMS anche quando errati). Inoltre, è necessario comunque che l'errore venga mostrato all'utente, per cui comunque lo script PHP deve riconoscere che si è verificato un errore nell'esecuzione di un comando SQL, capire a cosa è dovuto questo errore, e visualizzare il messaggio appropriato. Se a ciò aggiungiamo che MySQL offre solo un supporto limitato al trattamento dei vincoli di integrità, si capisce che questo è un approccio che è meglio lasciar perdere.

Modelli di validazione

Decidere come visualizzare i messaggi di errori dovuti alla presenza di dati sbagliati è un problema difficile. Se questo aspetto dell'applicazione viene pensato male, l'utente può trovarsi infastidito da continui messaggi di errori, difficili da eliminare, magari anche inaccurati o poco informativi. Non c'è niente di peggio che avere un messaggio che dice che si è verificato un errore ma non spiega in che campo di input c'è il problema.

La validazione è in realtà un processo composto da due fasi: trovare gli errori e presentarli all'utente.  La ricerca degli errori può essere:
Notare che la validazione interattiva è praticabile solo lato client. Se si volesse realizzare lato server, sarebbe necessario inviare i dati al server web ogni volta che l'utente modifica un campo di una form, causando una perdita di tempo inaccettabile.

Gli errori possono essere presentati all'utente in due modi:
Come per il caso precedente, quando la validazione è lato server la presentazione batch degli errori è preferibile, perché più efficiente. Visualizzare gli errori uno alla volta, chiedere di correggerli, e passare poi all'errore successivo richiede continui passaggi di dati tra browser e server web che renderebbero il tutto troppo lento.

In generale la soluzione migliore è avere una validazione batch a posteriori sul lato server assieme ad una validazione lato client (che può essere di qualunque tipo si desideri). Perché raddoppiare le validazioni?
  1. la validazione lato server è essenziale perchè non può essere aggirata dall'utente. In questo modo ci si assicura veramente che i dati inseriti rispettino tutti i vincoli richiesti.
  2. la validazione lato client è però più efficiente, e inoltre può essere sia eseguita a posteriori che interattiva, adattandosi quindi meglio al tipo di applicazione. Dunque, essa è opzionale ma altamente desiderabile.

ATTENZIONE! Purtroppo mentre PHP è indipendente dal browser che sta usando l'utente, lo stesso non vale per Javascript. Ne segue che, quando si adotta la validazione lato client, occorre controllare su vari tipi di browser che la validazione funzioni bene, visto che non tutto si comporta esattamente allo stesso modo con browser diversi.

Validazione batch della pagina di inserimento voli

Una prima soluzione al problema può essere data dallo script inserimento-validate-old.php. Questo controlla che il numero aereo e i codici aeroporto immessi dall'utente abbiano dei corrispettivo elementi nelle tabelle aerei e aeroporti. Qualora ciò non accada, invece di passare alla fase di inserimento viene visualizzata una pagina di errore.

È possibile tuttavia visualizzare gli errori in maniera più accattivante. Ad esempio, possamo modificare lo script in modo che, in caso di errore, venga rivisualizzata la pagina di inserimento dati, con in più l'elenco dei problemi che si sono verificati e con i campi di input già pre-riempiti. Si ottiene inserimento-validate.php.

In questo script abbiamo fatto uso di variabili di sessione per passare i valori immessi dall'utente dalla fase di controllo dati/inserimento alla fase di richiesta dati/visualizzazione errori. Una volta che queste variabili di sessione non servono più, è necessario eliminarle, e lo abbiamo fatto usando la seguente funzione:

Una alternativa sarebbe stata quella di utilizzare session_destroy, che però distrugge tutte le variabili di sessione. Nel caso ci fossero altre parti dell'applicazione che utilizzano variabili di sessione, questo potrebbe comprometterne il funzionamento. Ad esempio, nella applicazione airdb definitiva, la procedura di inserimento dovrà controllare che l'utente è autenticato (qui abbiamo tolto i controlli per semplicità). Eseguire una session_destroy vorrebbe dire impedire il riconoscimento dell'utente.

Esercizio

Modificare inserimento-validate in modo tale che, quando si verifica un errore, i campi di input che sono stati riempiti con i dati sbagliati vengano visualizzati in corsivo. A questo proposito, è possibile usare il tag <em>.

Validazione interattiva della pagina di inserimento voli

Visto che non è scopo del corso insegnare il JavaScript, mostriamo solo un esempio di come è possibile implementare un controllo interattivo lato client. Ovviamente, non è immediato controllare lato client se i valori immessi per il numero aereo o per i codici dell'aeroporto sono già presenti nella base di dati (anche se è possibile farlo). Per questo, controlliamo soltanto che nel campo relativo al numero di aereo venga inserito un valore numerico. Lo script che ci interessa è inserimento-js.php.

Lezione Precedente
Lezione Successiva

I file utilizzati in questa lezione: airdb3.sql, error.php, e .htaccess