SQLite, la database library di PHP 5
1. Introduzione a SQLite
Una delle maggiori novità proposte dalla versione 5 di PHP e il supporto nativo per SQLite. Si
tratta di una database library concepita in linguaggio C con lo scopo di implementare un DBMS
SQL da utilizzare all'interno di un'applicazione. SQLite è un software Open Source che può essere
liberamente utilizzato e modificato.
SQLite è una libreria, non un software come i DBMS più conosciuti quali per esempio MySQL e
PostgreSQL, quindi non è stata ideata per funzionare senza il supporto di un'interfaccia; per
sfruttarne le potenzialità dovremo infatti "dialogare" con essa utilizzando un linguaggio apposito
come per esempio PHP.
Per installare SQLite in PHP è necessario controllare che tra le llibrerie disponibili vi sia
"php_sqlite.dll", quindi nel PHP.ini si dovrà decommentare o aggiungere la voce:
extension=php_sqlite.dll
L'uso di SQLite presenta numerosi vantaggi; innanzitutto si tratta di una libreria che richiede
pochissimo spazio nel disco rigido, all'incirca 250 KB; questa caratteristica contribuisce a rendere i
processi ad essa correlati molto rapidi e poco dispendiosi in termini di risorse.
Un'altra caratteristica da segnalare è quella riferita all'aderenza delle transazioni di SQLite allo
schema ACID (Atomicity, Consistency, Isolation and Durability), cioè:
1. Atomicità, per cui ogni transazione è indivisibile durante l'esecuzione;
2. Consistenza, per cui viene salvaguardata la consistenza del database all'inizio, durante e alla
fine della transizione;
3. Isolamento, per cui ogni transazione viene eseguita isolatamente e indipendentemente dalle
altre;
4. Durabilità, per cui le modifiche apportate divengono persistenti e non vengono predute.
Naturalmente, quando si decide di utilizzare SQLite è bene tenere conto di alcuni importanti limiti
che ha questa libreria rispetto ai DBMS più evoluti. Tra gli altri citiamo:
• Non prevede l'utilizzo di alcuni comandi SQL quali, per esempio, RIGHT e FULL OUTER
JOIN; tra l'altro lo stesso comando ALTER TABLE risulta abbastanza limitato.
• Non è possibile eseguire sottoquery variabili nè transazioni annidiate.
• Non sono supportate le Stored Procedures nè i comandi relativi alla getione di permessi e
utenti.
• La gestione dei file binari non è stata implementata in modo ottimale.
Consci dei vantaggi e dei limiti di SQLite, nei prossimi articoli andremo ad analizzarne
l'interazione con PHP.
2. Creazione di un database con SQLite e PHP 5
La descrizione delle procedure d'interfacciamento tra SQLite e PHP 5, ci permettono di affrontare
parallelamente il discorso relativo alla programmazione orientata agli oggetti in PHP (OOP).
Nell'esempio che proporemo di seguito vedremo come sia possibile creare un database, inserire in
esso una tabella e popolare quest'ultima utilizzando PHP e SQLite:
<?
//creazione del database
$data = new SQLiteDatabase("test.sqlite");
//query per la tabella e i campi
$data->query("BEGIN;
CREATE TABLE tabella (id INTEGER PRIMARY KEY, dato VARCHAR(255));
INSERT INTO tabella (dato) VALUES('Lino');
INSERT INTO tabella (dato) VALUES('Pino');
INSERT INTO tabella (dato) VALUES('Nino');
COMMIT;");
//query di selezione
$res = $data->query("SELECT * FROM tabella");
//ciclo per la stampa dei dati
while ($res->valid())
{
$r = $res->current();
print_r($r);
$res->next();
}
//distruzione della connessione
unset($data);
?>
Da cui otteremo un output simile al seguente:
Array([0]=>1 [id]=>1 [1]=>Lino [dato]=>Lino)
Array([0]=>2 [id]=>2 [1]=>Pino [dato]=>Pino)
Array([0]=>3 [id]=>3 [1]=>Nino [dato]=>Nino)
Come si sarà potuto notare, la procedura da seguire per interfacciare PHP a SQLite tramite OOP è
molto semplice e, nella concezione, non differisce in modo particolare da quella utilizzata
comunemente con i software DBMS.
Da notare come SQLite sia in grado di distinguere i dati di tipo stringa da quelli numerici; questa
caratteristica è dovuta in particolare a ragioni di compatibilità e torna utile soprattutto nelle
operazioni di estrazione. Se i dati da allocare sono destinati unicamente all'allocazione e non
all'estrazione, sarebbe comunque possibile ometterne il tipo.
3. Funzioni correlate a SQLite
L'integrazione di SQLite all'interno di PHP 5 ha permesso agli sviluppatori di quest'ultimo di
introdurre alcune funzioni specifiche per questa libreria. Le funzioni in questione sono numerose e
lasciamo al lettore la possibilità di approfondirne le caratteristiche tramite la consultazione della
sezione apposita nella guida ufficiale a PHP.
In questo articolo e nei prossimi ne introdurremo solo alcune corredate da esempi pratici sul loro
utilizzo:
<?
$data = new SQLiteDatabase("test.sqlite");
$res = $data->arrayQuery(
"SELECT * FROM tabella", SQLITE_ASSOC);
print_r($res);
?>
SQLITE_ASSOC, più un costrutto sintattico che una funzione, ci permette di ottenere in output un
array associativo sulla base dei dati estratti dalla nostra tabella; infatti il risultato dello script appena
proposto sarà simile al seguente:
Array(
[0] => Array([id] => 1 [dato] => Lino)
[1] => Array([id] => 2 [dato] => Pino)
[2] => Array([id] => 3 [dato] => Nino)
)
Vediamo ora un breve script in cui potremo rilevare alcune interessanti funzioni di uso comune:
<?
$data = sqlite_open("test.sqlite");
//ricerca dell'id
$i = sqlite_single_query ($data, "SELECT id FROM tabella WHERE dato='Lino'");
var_dump($i);
//i dati corrispondenti saranno più di 1
//quindi verrà generato un array
$is = sqlite_single_query ($data, "SELECT id FROM tabella WHERE dato LIKE
'%o'");
var_dump($is);
?>
La prima query estrae l'Id di un determinato dato, per cui il risultato sarà la stampa della variabile
corrispondente; la seconda query ricerca tutti i record in cui il contenuto del campo "dato" finisce
con la lettera "o", nel nostro caso questa caratteristica è posseduta da tutti i record, quindi il risultato
in output sarà un array.
La funzione sqlite_open() apre un database SQLite o lo crea se non esiste; sqlite_single_query()
esegue invece una query e genera o una matrice per ogni singola colonna o semplicemente il valore
della prima riga.
4. Iteratori e utility di PHP 5 per SQLite
Un metodo abbastanza comune per l'estrazione dei record da un database SQLite tramite PHP è
quello di utilizzare l'iterazione; dato che stiamo parlando di gestione degli array, è naturale pensare
che il più importante costrutto di iterazione utilizzabile sarà senz'altro foreach:
<?
$data = new SQLiteDatabase("test.sqlite");
$rs = $data->unbufferedQuery("SELECT * FROM tabella");
foreach ($rs as $r)
{
print_r($r);
}
?>
Nello specifico, SQLiteDatabase->unbufferedQuery esegue una query sul database senza
scaricare e bufferizzare i dati, i risultati vengono restituiti in modo sequenziale una riga dopo l'altra,
si consente così soltanto la lettura del record successivo.
Questo costrutto si rivela particolarmente utile nel caso di output "impegnativi" come per esempio
la generazione di tavole HTML in cui è necessario processare una riga per volta e non muoversi a
caso tra le righe.
Un'altra utilità messa a disposizione da PHP 5 per le nostre query su database SQLite è
sqlite_num_fields(), questa funzione resituitsce il numero di campi da un set di risultati; è infatti
molto utile per la numerazione dei campi, di una tabella:
<?
$data = new SQLiteDatabase("test.sqlite");
$rs = $data->unbufferedQuery("SELECT * FROM tabella LIMIT 1");
$n_campi = $rs->numFields();
$j = 0;
while ($j < $n_campi)
{
$nome_campo = $rs->fieldName($j++);
echo $nome_campo." ".$j. "<br />";
}
?>
Come si avra avuto modo di notare dal test del codice proposto, lo scopo del costrutto
SQLiteUnbuffered->fieldName è quello di restituire il nome di un particolare campo
5. Creazione di funzioni PHP personalizzate per SQLite
In questo articolo finale vedremo come concepire una funzione personalizzata per le nostre query su
SQLite; nello specifico creeremo una funzione che ci permetterà di effettuare un confronto tra una
stringa da noi definita e il contenuto dei record della nosta tabella.
Proponiamo di seguito il codice completo attraverso il quale abbiamo sviluppato la nostra funzione
denominata "confronta":
<?
//definizione della funzione
function confronta($dato, $str)
{
return similar_text($dato, $str);
}
//istanza della classe riferita al database
$data = new SQLiteDatabase("test.sqlite");
//introduzione della funzione
//il parametro numerico indica il numero di argomenti da passare alla funzione
$data->createFunction('confronta', 'confronta', 2);
//esecuzione della query e definizione della stringa per il confronto
$rs = $data->arrayQuery("SELECT dato, confronta(dato,'Pin') AS confronto
FROM tabella", SQLITE_ASSOC);
//stampa dei risultati
print_r($rs);
?>
La logica attraverso la quale è stata sviluppata la funzione è abbastanza semplice da comprendere;
anche in questo caso sono state utilizzate alcuni costrutti predefiniti degni di nota:
SQLiteDatabase->arrayQuery, abbiamo già incontrato la funzione sqlite_array_query(), esegue
una query in un determinato database e restituisce da questa una matrice; SQLiteDatabase>createFunction permette invece di registrare una funzione utente "regolare" da utilizzare nelle
istruzioni SQL.