Ora che abbiamo a disposizione la connessione al database possiamo iniziare a lavorare con i dati, in particolare ci dedicheremo alle operazioni in scrittura su un database. Innanzitutto supponiamo di avere a disposizione un database MySQL al quale connettersi:
try {
$db = new PDO('mysql:host=localhost;dbname=corso', $user, $pass);
} catch (PDOException $e) {
echo "Errore: " . $e->getMessage();
die();
}
Nel database corso
avremo una tabella utenti
dove il campo id
è la chiave primaria autoincrementale:
CREATE TABLE utenti (
id int(11) NOT NULL,
nome varchar(255) COLLATE utf8_unicode_ci NOT NULL,
cognome varchar(255) COLLATE utf8_unicode_ci NOT NULL,
email varchar(255) COLLATE utf8_unicode_ci NOT NULL,
anno_nascita year(4) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Inserire record
Il primo punto da affrontare è l'inserimento dei record nella tabella. PDO mette a disposizione diverse possibilità, più o meno "raccomandabili". La prima consiste nel creare una query ed eseguirla direttamente dalla pagina PHP:
$db->query("INSERT INTO utenti(nome, cognome, email) VALUES('lorenzo','de ambrosis','email@test.it','1973')");
Soluzione semplice ma in realtà poco praticabile: infatti quasi sempre alle stringhe dovremo sostituire delle variabili:
$db->query("INSERT INTO utenti(nome, cognome, email) VALUES('$nome','$cognome','$email','$anno')");
L'esecuzione diretta della query proposta dell'esempio ci espone però al rischio di SQL INJECTION dato che non c'è nessun controllo sul dato inserito. L'unica possibile opzione è quella di usare il metodo quote
che funziona come mysql_real_escape_string()
, ma non è la soluzione ottimale.
. Sarà quindi opportuno passare alle query parametriche.
Query parametriche
La struttura della nostra query cambierà ora notevolmente, avremo infatti le fasi prepare, il bind dei parametri e infine l'esecuzione della query. Iniziamo quindi a definire l'istruzione SQL:
$sql = "INSERT INTO utenti(nome, cognome, email) VALUES(':nome',':cognome',':email',':anno')");
La differenza rispetto all'approccio precedente sta nella sostituzione delle variabili, per esempio $anno
viene rappresentato dal parametro :anno
. A questo punto possiamo preparare la nostra query:
$stmt = $db->prepare($sql);
E a questo punto eseguiamo il bind dei parametri:
$stmt->bindParam(':nome', $nome, PDO::PARAM_STR);
Il metodo bindParam
accetta 3 argomenti, il nome del parametro, il valore del parametro e infine il tipo di dato, parametro opzionale.
Infine, ultimo step, introduciamo il metodo execute
:
$stmt->execute();
L'istruzione SQL e i parametri vengono spediti separatamente al database server (motivo per il quale non sarà possibile stampare la query "completa") e solo dopo la query verrà finalmente eseguita. Questo modo di procedere è quello che ci fornisce una maggiore sicurezza rispetto ai pericoli derivanti dall'iniezione di codice SQL.
bindParam vs. bindValue
Un approfondimento necessario riguarda la differenza fra bindParam
e bindValue
: bindValue
associa il valore della variabile al parametro, bindParam
referenzia invece la variabile agganciandola al parametro, in poche parole con bindValue
non possiamo modificare il valore associato, mentre usando bindParam
verrà usato il nuovo valore se quello della variabile cambia tra il bind e l'execute.
Quindi mentre
$sql = "INSERT INTO utenti(nome) VALUES(':nome');
$stmt = $db->prepare($sql);
$nome = 'Lorenzo';
$stmt->bindValue(':nome', $nome, PDO::PARAM_STR);
$stmt->execute();
inserirà il valore "Lorenzo"
$sql = "INSERT INTO utenti(nome) VALUES(':nome');
$stmt = $db->prepare($sql);
$nome = 'Lorenzo';
$stmt->bindParam(':nome', $nome, PDO::PARAM_STR);
$nome = 'Pippo';
$stmt->execute();
inserirà il valore "Pippo".