In questo articolo PHP saranno mostrate alcune tecniche per poter estrarre dati da una tabella di un database relazionale qualsiasi utilizzando un oggetto di tipo PDO. Nel caso fosse necessario un ripasso delle caratteristiche della classe PDO allora potrebbe interressare questo articolo che ho precedentemente redatto.
L'utilizzo di istanze della classe PDO per eseguire operazioni di estrazione dati da database consente di poter approcciare il problema in almeno un paio di modi differenti. Ma prima di tutto la base dati.
La tabella Dipendenti
Come base dati di esempio per il proseguio dell'articolo sarà utilizzata una tabella fittizia di possibili dipendenti, di una qualunque società, residente in un database MySQL.
La tabella scelta si chiama Dipendenti,è composta di soli campi stringa ed è così strutturata:
| matr | nome | cognome | nascita | cf |
|---|---|---|---|---|
| 000AAA1 | Mirko | Agrati | 06/12/1975 | zzzaaaag7887dhsg |
| 000AAA2 | Pippo | Rossi | 26/11/1990 | z44rsaag5811dhsk |
| 000AA02 | Luca | Bianchi | 11/03/1980 | j77ssrtm3321azpp |
Nota.
Entrambi gli script danno per scontata la conoscenza della corretta struttura e sintassi di un DSN (o Data Source Name), necessario per aprire una connessione a qualunque database utilizzando un'istanza della classe PDO. L'articolo consigliato nell'introduzione riporta le informazioni necessarie a riguardo.
Estrazione tramite il metodo query()
Il metodo PDO->query() è comodo da utilizzare per eseguire query che vengono richieste raramente. Non esegue automaticamente l'escape dei dati utilizzati però permette facili iterazioni sui dati restituiti da una SELECT SQL.
Segue esempio:
$matricola_radice = '000AAA';
try{
$dbh = new PDO($dsn, $user, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
$sql = 'SELECT * FROM DIPENDENTI WHERE matr LIKE ' .
$dbh->quote($matricola_radice . '%');
foreach ($dbh->query($sql) as $row) {
print $row['nome'] . "\t";
print $row['cognome'];
}
}
catch (PDOException $e){
echo 'Si è verificata una eccezione PDO Exception.';
echo 'Errore restituito dal DB:
';
echo 'SQL Query: ', $sql;
echo 'Errore: ' . $e->getMessage();
}
Pur essendo un valido modo per estrarre dati, a causa delle attenzioni in fatto di sicurezza che bisogna dedicare ai dati inseriti, il suo utilizzo è sconsigliato mentre è favorito quello che prevede l'utilizzo di prepared statements.
Estrarre dati utilizzando i metodi prepare() and execute()
L'utilizzo dei metodi PDO->prepare() e PDO->execute() è sicuramente la soluzione più vantaggiosa per poter gestire query SQL eseguite di frequente.
I vantaggi che questa scelta comporta sono prima di tutto in termini di sicurezza e della qualità dei dati trattati, questo grazie ad automatismi presenti per prevenire attacchi tramite SQL Injection, ed i dati vengono sempre escapati tutti;
il secondo motivo per cui è consigliato utilizzare questa via consiste nel fatto che i prepared statements richiedono meno risorse e ottengono performances migliori di ripetute chiamate al DB.
$matricola_radice = '000AAA';
try{
$dbh = new PDO($dsn, $user, $password);
$sql = 'SELECT * FROM DIPENDENTI '
. 'WHERE matr LIKE :matricola_radice' . '%';
$dbh->setAttribute(PDO::ATTR_ERRMODE
, PDO::ERRMODE_EXCEPTION);
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':matricola_radice'
, $matricola_radice, PDO::PARAM_STR);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
print $row['Nome'] . "\t";
print $row['Cognome'];
}
}
catch (PDOException $e){
echo 'Si è verificata una eccezione PDO Exception.';
echo 'Errore restituito dal DB:
';
echo 'SQL Query: ', $sql;
echo 'Errore: ' . $e->getMessage();
}
Il metodo prepare() riceve come parametro la query SQL e restituisce un'istanza della classe PDOStatement alla quale, tramite il metodo bindParam() passiamo il valore ed il tipo di ogni variabile dichiarata, e sul quale viene invocata la chiamata al metodo execute().
Infine, viene eseguito un ciclo per scorrere i record estratti, fin che è possibile eseguire una fetch.
Personalmente, abituato ad sviluppare su piattaforma JEE, prediligo il secondo approccio perché mi ricorda il modo di utilizzo delle librerie Java JDBC e garantisce dei buoni controlli di correttezza e sicurezza dei dati eventualmente inseriti.
Alla prossima,
MA.