[Download]. Versione 1.01 del 2011-05-12.
Mancolista è l'applicazione di esempio sviluppata passo passo durante il corso di Laboratorio di Sistemi Informativi. Potete trovare la descrizione originale dell'applicazione nella lezione La mancolista di Paolo. Rispetto a questa descrizione, sono state fatte alcune modifiche:
Rispetto a quanto visto a lezione, abbiamo spostato le funzionalità di prenotazione all'interno della pagina di dettagli, come era previsto inizialmente dalle specifiche, e non nella pagina dell'elenco oggetti.
L'archivio compresso che scaricate contiene il file mancolista.sql
, che è lo script SQL necessario a creare e popolare il database (leggermente diverso da quello usato durante il corso, dovuta all'eliminazione del campo confermato
della tabella oggetti
), e una serie di pagine PHP che implementano l'applicazione. Il file config.inc.php
contiene la definizione dei parametri di connessione (CONNECTION
, USERNAME
, PASSWORD
) visti a lezione e del parametro DEBUG
. Quest'ultimo è da impostare a true
durante lo sviluppo dell'applicazione, quando si vogliono visualizzare i messaggi di errore, e a false
durante l'utilizzo, quando non si vogliono visualizzare. È presenta anche un file Changelog
che contiene l'elenco delle modifiche apportate all'applicazione nel corso della sua storia.
Ogni script PHP implementa una funzionalità ben precisa. Le funzionalità che richiedono più fasi (cancellazione, modifica, inserimento) sono implementate sempre con un'unico script, diviso in più parti. Tuttgli gli script includono all'inizio il file common.inc.php
(l'uso del .inc
serve a far capire che si tratta di un file da includere in altri, ma per evitare problemi di esposizione delle credenziali di accesso, comunque il file termina con l'estensione .php
). Il file comprendela definizione di alcune funzioni di utilità generale, tra cui
redirect_browser
: l'abbiamo vista più volte a lezione.h
e u
: sinonimi di htmlspecialchars
e rawurlencode
(così nel resto delle pagine possiamo usare h
ed u
che sono più corte da scrivere).set_flash
: per visualizzare dei messaggi al termine di qualche operazione utilizziamo il metodo di scrivere il messaggio in una variabile di sessione ($_SESSION['flash_message']
) e invocare con redirect_browser
la pagina dove il messaggio verrà visualizzato (come fatto nella lezione su Concorrenza nelle applicazioni web). Tuttavia, preferiamo non manipolare mai direttamente la variabile di sessione nelle pagine PHP, ma utilizziamo la funzione set_flash
. In questo modo, se decidessimo di cambiare l'implementazione, dovremmo modificare solo il file common.inc.php
.showHeader
e showFooter
: tutte le pagine HTML che generiamo hanno sempre dei pezzi in comune all'inizio (le intestazioni HTML, lo spazio per i messaggi flash (vedi sopra), etcc...). Lo stesso dicasi, seppure in misura minore, dei pezzi in comune alla fine (i tag di chiusura body
e html
. Invece di ripetere questi tag in ogni pagina, le funzioni showHeader
e showFooter
si occupano di generare i pezzi comuni iniziali e finali, e vengono chiamati nel momento in cui serve iniziare una pagina HTML o concluderla.showHeader
si occupa anche di impostare il set di caratteri delle pagine web a UTF-8, in modo che i caratteri accentati vengano visualizzati correttamente. Non ci siamo occupati di questo argomento a lezione, quindi potete tranquillamente ignorarlo, ma se vi interessa approfondire potete consultare la lezione Set di caratteri e codifica delle stringhe dell'anno accademico 2008-09.print_label_with_error
: è una funzione di utilità che semplifica la scrittura delle pagine di modifica e inserimento dati. Visualizza una stringa in un colore normale o rosso (utilizzando delle classi CSS) a seconda degli elementi presenti nella variabile $_SESSION['errors']
. Si veda l'esercizio 1 della lezione Validazione dati.
logError
: Visualizza un messaggio di errore e termina l'esecuzione del programma. Se la costante DEBUG
è true
visualizza un messaggio dettagliato, altrimento solo un messaggio generico. La funzione si occupa anche di impostare il set di caratteri a UTF-8 (vedi discussione in merito alla funzione showHeader
) e di manipolare il buffer di output con ob_end_clean
. Quest'ultimo argomento non è stato discusso a lezione, e potete ignorarlo, ma chi è interessato può consultare la lezione Gestione degli errori dell'anno accademico 2008-09. In prospettiva, si potrebbe anche far in modo che, quando DEBUG
è false
i messaggi di errori dettagliato vengano salvati in un file sul server, per poter essere consultati dallo sviluppatore dell'applicazione, ma questa funzionalità non è stata implementata.exceptionHandler
e errorHandler
: sono i gestori di default delle eccezioni e degli errori, ovvero delle funzioni PHP che vengono automaticamente chiamati quando si verifica una eccezione non catturata o un errore non fatale. L'argomento non è stato discusso a lezione, e potete ignorarlo, ma chi è interessato può consultare la lezione Gestione degli errori dell'anno accademico 2008-09 (dove, però, non viene spiegata la exceptionHandler
).is_admin
, set_admin
, is_logged
, get_user_id
e set_user_id
: l'applicazione usa le variabili di sessione $_SESSION['userid']
per memorizzare l'id dell'utente correntemente loggato e $_SESSION['admin']
per indicare se l'utente loggato è amministratore oppure no. Invece di manipolare direttamente questa variabili in tutto il programma, le varie pagine PHP chiamano queste funzioni, che si occupano loro del lavoro di leggere e manipolare le giuste variabili di sessione. In questo modo se decidessimo di cambiare l'implementazione della gestioen utenti, dovremmo modificare solo il file common.inc.php
.A parte la definizione delle funzioni, il file common.inc.php
si occupa anche di:
exceptionHandler
e errorHandler
come gestori predefiniti di eccezioni ed errori (vedi sopra);ob_start()
(vedi logError
qui sopra);$conn
, così che tutte le pagine possano usare questa connesione.Tutto il resto dovrebbe essere comprensibile guardando il codice sorgente PHP delle varie pagine. La modifica più sostanziale rispetto a ciò che abbiamo visto a lezione è che le pagine di inserimento oggetti e modifica oggetti (così come inserimento utenti e modifica utenti, che però non abbiamo visto a lezione) sono fuse in un unico script modifica_oggetti.php
. Infatti le due funzionalità condividono gran parte del codice, e duplicarlo sarebbe inutile e dannoso. Per distinguere il caso in cui si sta effettuando un inserimento da quello in cui si sta effettuando una modifica, si guarda il parametro $_GET['id']
: se esiste, contiene l'id dell'oggetto da modificare, altrimenti stiamo inserendo un nuovo elemento. Ovviamente bisogna stare attenti a non perdere il parametro "per strada" quando si passa dalla form di richiesta dati alla fase di manipolazione del database e viceversa.
L'applicazione dovrebbe essere resistente ad attacchi di tipo Cross Site Scripting e SQL Injection. Non siamo stati invece molto previdenti sul fronte degli attacchi Buffer Overflow: tronchiamo gli input solo nelle procedure di modifica/inserimento di oggetti e utenti, per il resto confidiamo nella corretta implementazione di PHP e MySQL. Per ciò che riguarda la validazione dei dati, usiamo un approccio molto permissivo: controlliamo solo alcune cose fondamentali (ad esempio che ogni oggetto abbia un nome non vuoto), ma per il resto accettiamo di tutto. Non proviamo a riconoscere un tentativo di attacco ma, quando qualcosa non va bene (ad esempio uno script viene chiamato senza i parametri richiesti) semplicemente redirigiamo l'applicazione ad una pagina opportuna.
Per quanto riguarda la concorrenza, gestiamo correttamente le operazioni che riguardano prenotazioni e messaggi, ma ignoriamo il problema degli utenti: se un utente si loggato e nel frattempo un amministratore lo cancella, la cosa non viene riconosciuta, e il database si può ritrovare in uno stato inconsistente. Magari in una prossima versione!