Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 15 di 56
  • livello intermedio
Indice lezioni

PDO: operazioni di scrittura sul database

Impariamo ad utilizzare i metodi di PDO per scrivere dati in un database MySQL con PHP e scopriamo quali accorgimenti adottare per evitare i pericoli della SQL INJECTION.
Impariamo ad utilizzare i metodi di PDO per scrivere dati in un database MySQL con PHP e scopriamo quali accorgimenti adottare per evitare i pericoli della SQL INJECTION.
Link copiato negli appunti

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".

Ti consigliamo anche