Abbiamo visto nella parte 1a di questo articolo come gestire questa nuova tecnologia che gestisce il flusso dei dati da e verso il database. Proseguiamo con i PHP Data Object parte 2a.
Indice
PHP Data Object, PDO – parte 2a – La gestione dei dati
Il parametro PDO::ATTR_DEFAULT_FETCH_MODE, gestisce il “fetch” dei dati e dispone delle opzioni:
– PDO::FETCH_BOTH, (default) restituisce un array con indice che parte da 0 e anche il nome della colonna. Quindi sia nome che numero della colonna.
array( [codice] => "test", [0] => "test" )
– PDO::FETCH_ASSOC, restituisce un array che ha come indice quello del nome della colonna del db.
array( [codice] => "test" )
– PDO::FETCH_NUM, restituisce un array che ha come indice il numero della colonna del db a partire dalla colonna con indice 0.
array( [0] => "test" )
PDO::FETCH_OBJ, restituisce un oggetto che ha il nome della colonna del db.
stdClass Object ( [codice] => "test" )
Ci sono due parametri da assegnare a PDO che possono avere una certa importanza:
- PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, che ovviamente riguarda solo il database MySQL. Se lo impostiamo a TRUE, consente di eseguire più query alla volta.
- PDO::ATTR_TIMEOUT, da la possibilità di impostare un tempo limite per le query da esprimere in secondi.
Come eseguire una query – query()
Il metodo più semplice e veloce per effettuare una query, da non usare per applicazioni produttive ma solo per il test perché c’è la vulnerabilità SQL Injection:
foreach($connessione->query("SELECT * FROM articoli WHERE id = 1 LIMIT 1") as $row) {
echo $row["codice"];
echo $row["descrizione"];
}
Per ovviare al problema degli apici della SQL Injection PDO ha il metodo quote() che ricorda la vecchia funzione mysql_real_escape_string:
$connessione->quote("Questa 'stringa' ha alcuni 'apici singoli'");
Query in modo sicuro con il metodo prepare()
Questo nuovo metodo invia dapprima la query grezza con delle variabili che andranno poi sostituite con quelle da noi desiderate. Solo in una seconda fase vengono inviati i dati. Ecco come eseguire un prepared statement:
$risultati = $connessione->prepare("SELECT * FROM articoli WHERE id = :id LIMIT 1");
$risultati->execute(array(
":id" => $id
));
echo "Test metodo -> prepare()"
while($row = $risultati->fetch()) {
echo "Codice articolo: " . $riga["codice"];
echo "Descrizione: " . $riga["descrizione"];
}
Il metodo exec()
Esegue una query in una sola chiamata e invece di restituire i risultati di quest’ultima, restituisce il numero di righe. Non serve quindi usarlo con il comando SELECT, perchè non darebbe risultati, ma da usare con UPDATE e DELETE. Ha le stesse caratteristiche del metodo query(), quindi non c’è nessuna prevenzione contro eventuali attacchi.
$num_ris = $connessione->exec("DELETE * FROM articoli WHERE scadenza = 2016-10-01");
echo "Sono stati elimati " . $num_ris . " Articoli ";
L’oggetto PDOStatement
La chiamata delle funzioni query(), prepare(), exec() attiva l’oggetto PDOStatement che ha le seguenti funzioni:
- PDOStatement::closeCursor, chiude la connessione al db per poter eseguire altre query.
- PDOStatement::setFetchMode, attiva il fetch. Stessa funzione di PDO::ATTR_DEFAULT_FETCH_MODE, on-fly
- PDOStatement::rowCount, dà il numero di righe risultato di una query, con i comandi UPDATE, DELETE, INSERT, e con alcuni db anche con il comando SELECT.
- PDOStatement::debugDumpParams, dà un array che contiene le informazioni dell’ultimo prepared statement, con i valori assegnati ai placeholder.
- PDOStatement::fetchAll, come la funzione fetch(), con la differenza che calcola un risultato alla volta, fetchAll() dà un array con indice 0 che ha tutti i dati della query.
N.B. fetchAll() è più veloce ma impegna più memoria rispetto a fetch().
Una grossa novità che offre PDO sono le transazioni. Con il loro utilizzo è possibile tornare indietro e annullare l’ultima query eseguita. Con il metodo beginTransaction() si disabilita momentaneamente la logica autocommit() del db ed è possibile annullare la query con il metodo rollBack(). Ecco un semplice esempio di codice:
// Sospendere la funzione del DB auto-commit
$conn->beginTransaction();
try {
$cancella = $conn->exec("UPDATE articoli SET codice = 'AX200' WHERE id = 52");
$conn->commit();
} catch(Exception $e) {
// Attiviamo nuovamente l'auto-commit
$conn->rollBack();
die("Errore non verificato " . $e->getMessage());
}
Conclusioni
Abbiamo visto in questo articolo questa nuova tecnologia per la gestione dei dati da e verso il database PHP Data Object parte 2a. Vista la rilevanza dell’argomento e visto il grande numero di richieste che ci sono pervenute a proposito della gestione dei Form e delle Aree Riservate, questo Portale ha tutta una sezione riservata al linguaggio di programmazione PHP. In questa sezione oltre a tanti esempi di codice, troverete anche strumenti utili per la programmazione come Framework, librerie e tanto altro. Vi invitiamo quindi a visitare questa sezione del sito e ricordiamo che è disponibile anche una sezione esempi di codice PHP come quello che abbiamo proposto in questo articolo.
