Dopo aver creato la struttura delle tabelle passiamo ad analizzare l'inserimento e la lettura dei dati tramite la libreria MySQLi. È naturale per un'applicazione Web con un'interfaccia di backend verificare l'accesso degli operatori autorizzati tramite le credenziali memorizzate in una apposita tabella di login. Per quest'ultima, lo ricordiamo, abbiamo predisposto i campi id
, user
e password
.
Nel campo password
non inseriremo comunque del testo in chiaro, ma l'hash di 64 caratteri della password generato tramite la funzione SHA256 disponibile nativamente in PHP.
Inserimento dei dati nelle tabelle
L'inserimento dei dati avviene tramite query SQL con la parola chiave INSERT
processata da MySQLi tramite il metodo query()
:
// Connessione al database
$mysqli = new mysqli('localhost', 'root', 'root', 'biblioteca');
if ($mysqli->connect_error) {
die('Errore di connessione (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
$password = hash('sha256', 'paperino'); //Creazione dell'hash
$query = "INSERT INTO login (user, password) VALUES ('pippo', '$password')";
// Esecuzione della query e controllo degli eventuali errori
if (!$mysqli->query($query)) {
die($mysqli->error);
}
Abbiamo detto in precedenza che il metodo query()
restituisce il valore false
nel caso in cui MySQL risponda alla richiesta con un messaggio di errore per il debug. Non è tuttavia l'unico dato che possiamo ricavare dopo l'esecuzione della query, altre due informazioni che potrebbero risultare molto utili sono il numero delle righe generate e, trattandosi di un inserimento all'interno di una tabella con una campo autoincrement
, l'ultimo ID inserito.
Per testare il semplice funzionamento dei metodi affected_rows()
e insert_id()
, applicabili all'istanza della classe mysqli_result
ottenuta come risultato dal metodo query, al termine del codice possiamo aggiungere queste righe:
echo "Righe generate: " . $mysqli->affected_rows . "<br />";
echo "Ultimo ID inserito: " . $mysqli->insert_id . "<br />";
Che stamperanno a schermo (naturalmente in assenza di errori):
Righe generate: 1
Ultimo ID inserito: 1
Verifica delle credenziali
Per verificare la correttezza delle credenziali dobbiamo passare alla lettura dei dati, utilizzando come parametri quelli inseriti dall'utente verosimilmente da un form. Un esempio di codice potrebbe essere il seguente:
// Connessione al database
$mysqli = new mysqli('localhost', 'root', 'root', 'biblioteca');
if ($mysqli->connect_error) {
die('Errore di connessione (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
$user = "pippo"; // Normalmente questi valori sarebbero ottenuti tramite POST
$password = hash('sha256', "paperino");
$query = $mysqli->query("SELECT * FROM login WHERE user = '$user' AND password = '$password'");
if($query->num_rows) {
echo "Accesso consentito";
} else {
echo "Accesso rifiutato";
}
Il metodo num_rows()
, sempre applicabile alla classe mysqli_result
, restituisce il numero di righe ottenute dalla select e avremo quindi un risultato superiore a 0 solo nel caso in cui le credenziali siano valide.
La classe mysqli_result
dispone di metodi per lavorare sui dati ottenuti, ad esempio per ottenere un array con i record ottenuti dalla query possiamo utilizzare il metodo fetch_all
:
if($query->num_rows) {
echo "<pre>"; // Il tag pre rende facilmente leggibile l'array
print_r($query->fetch_all(MYSQLI_BOTH));
echo "</pre>";
} else {
echo "Accesso rifiutato";
}
fetch_all()
è un metodo molto flessibile, che produce un array per ogni record, numerico (MYSQLI_NUM
), associativo (MYSQLI_ASSOC
) o di entrambe le tipologie (MYSQLI_BOTH
) a seconda della costante che passeremo come argomento. Il codice proposto produrrà quindi come risultato:
Array
(
[0] => Array
(
[0] => 1
[id] => 1
[1] => pippo
[user] => pippo
[2] => f106e246ecdab88cb2262780f60079651aeaa6a3c8f5b1e75fc2ab0582cd3f67
[password] => f106e246ecdab88cb2262780f60079651aeaa6a3c8f5b1e75fc2ab0582cd3f67
)
)
Esamineremo altri metodi per la lettura dei dati, pensati ad esempio per leggere singoli record o per generare degli oggetti al posto degli array, man mano che procederemo nella nostra applicazione.
La necessità dei prepared statements
Non è tuttavia questo il codice che consigliamo di usare per query dei dati che provengono direttamente dall'utente. Infatti ogni volta che i dati che entrano nell'applicazione provengono dall'input dell'utente è necessario cautelarsi da minacce come la SQL injection.
L'estensione MySQLi può aiutarci tramite i prepared statements, una particolare tecnica che complica leggermente il semplice procedimento appena descritto, ma che offre diversi vantaggi sia a livello di pulizia del codice che di sicurezza.
Nella prossima lezione mostreremo quindi come funzionano i prepared statements e come leggere i dati da essi ottenuti.