Pur nel pieno rispetto delle sue caratteristiche fondamentali di semplicità, leggerezza e alte performance, CodeIgniter (leggi l'articolo di introduzione a CodeIgniter) è stato integrato con tutti gli strumenti necessari per l'interazione tra applicazioni e database; una qualità che lo rende un framework da prendere in considerazione anche per lo sviluppo di progetti complessi.
In questa breve trattazione analizzeremo le metodologie necessarie per permettere a CodeIgniter di dialogare con i DBMS, ponendo particolare attenzione alla minima procedura di configurazione richiesta, alle classi, ai metodi e alle funzioni che entrano in gioco per la relazione del framework con i database.
Configurazione di CodeIgniter per l'interazione con i database
Anche nel caso dell'interazione con i Database server, CodeIgniter mantiene la sua caratteristica di semplicità in fase di configurazione; il codice del file database.php, che si trova sul percorso application/config/, contiene un array multidimensionale al quale possono essere passati come valori i parametri per la connessione al DBMS e per la selezione del database così come altri argomenti che descrivono il tipo di interazione; analizziamo queste voci nello specifico:
# hostname del proprio Database server $db['default']['hostname'] = "localhost"; # nome dell'utente con il quale connettersi $db['default']['username'] = "claudio"; # password per l'autenticazione dell'utente $db['default']['password'] = "secretkey"; # nome del database da selezionare $db['default']['database'] = "archivio"; # tipologia del database driver da utilizzare # deve essere specificato in lettere minuscole $db['default']['dbdriver'] = "mysql"; # prefisso delle tabelle # da utilizzare nel caso si abbiano più installazioni di # CodeIgniter che condividono una sola tabella $db['default']['dbprefix'] = "tb_"; # valore booleano, settato su TRUE consente le connessioni # persistenti, diversamente deve essere settato su FALSE $db['default']['pconnect'] = TRUE; # valore booleano, settato su TRUE consente le visualizzazione # degli errori, diversamente deve essere settato su FALSE $db['default']['db_debug'] = FALSE; # valore booleano, settato su TRUE abilita il query caching, # diversamente deve essere settato su FALSE $db['default']['cache_on'] = FALSE; # specifica il percorso assoluto alla directory # utilizzata per il caching delle query $db['default']['cachedir'] = ""; # specifica il set di caratteri da utilizzare # per comunicare con il database $db['default']['char_set'] = "utf8"; # specifica la collection di caratteri da utilizzare # per comunicare con il database $db['default']['dbcollat'] = "utf8_general_ci";
Nel caso in cui si utilizzi PostgreSQL sarà necessario aggiungere una nuova riga (e quindi un nuovo valore) all'array multidimensionale:
# specifica la porta di acolto del Database server
$db['default']['port'] = 5432;
Ma perché utilizzare un array multidimensionale invece di un semplice vettore o di una sequenza di variabili? Il motivo è semplice, in questo modo è possibile eventualmente memorizzare più set di valori per la connessione; sarà per esempio possibile utilizzare più ambienti (test, sviluppo, produzione etc.) attraverso un'unica installazione di CodeIgniter e creare un gruppo per la connessione di ognuno di essi.
Per utilizzare uno dei gruppi creati sarà sufficiente specificarne il nome associandolo ad una variabile presente nel file di configurazione:
$active_group = "nome_gruppo";
Connessione al database server con CodeIgniter
Esistono in CodeIgniter due modalità per la connessione al Database server, la prima (denominata Auto Connect) consente di mantenere sempre attiva la richiesta di interazione e l'istanza al database; per far questo è sufficiente agire sul file autoload.php presente nel percorso application/config/ e aggiungere la parola database all'array denominato libraries; nello stesso modo sarà possibile specificare l'autoload anche per oltre funzioni come per esempio la gestione delle sessioni:
$autoload['libraries'] = array('database', 'session');
Se invece si preferisce una procedura manuale più controllabile dall'utente, è preferibile ricorrere alla seconda tipologia di connessione; questa dovrebbe essere scelta nel caso in cui si desideri effettuare la chiamata al Database server soltanto dalle pagine che lo richiedono. Per far questo sarà sufficiente inserire la seguente linea di codice in tutte le funzioni per la quale è richiesta o nel costruttore di una classe che renderà la connessione disponibile globalmente all'interno della classe:
$this->load->database();
Nel caso in cui non dovesse essere passato alcun argomento alla funzione, il framework prenderà in considerazione il gruppo specificato nel file di configurazione per il database; diversamente sarà possibile precisare quale gruppo di connessione si desidera utilizzare:
$this->load->database('nome_gruppo');
CodeIgniter consente di connettersi a più database contemporaneamente indicando un'istanza differente per ognuno di essi:
$DB1 = $this->load->database('primo_gruppo', TRUE); $DB2 = $this->load->database('secondo_gruppo', TRUE);
Eseguire query con CodeIgniter
Per eseguire un'interrogazione su una tabella tramite il framework è necessario utilizzare la seguente sintassi basata sulla specifica funzione query()
:
$this->db->query('TESTO DELL'INTERROGAZIONE');
La funzione query()
restituisce un oggetto (database result object) una volta letta ed eseguita l'interrogazione, questo oggetto potrà poi essere utilizzato per mostrare un risultato anche quando associato ad una variabile:
$query = $this->db->query('TESTO DELL'INTERROGAZIONE');
Esiste poi una funzione denominata simple_query()
, utilizzabile in questo modo:
$this->db->simple_query('TESTO DELL'INTERROGAZIONE');
simple_query()
, è in grado di restituire soltanto TRUE oppure FALSE in caso di successo o di fallimento della query, mentre in nessun caso è in grado di restituire un risultato o di memorizzare l'interrogazione passata come argomento per operazioni di debugging, per questo motivo non viene utilizzata molto spesso.
Grazie alle funzioni messe a disposizione in CodeIgniter è anche possibile eseguire operazioni di escape dei dati, si tratta di strumenti che elevano il livello di sicurezza delle interrogazione in particolare quando si eseguono query per l'inserimento di nuovi record o per l'aggiornamento di essi.
In particolare sarà possibile effettuare l'escape delle interrogazioni attraverso due differenti funzioni: escape()
e escape_str()
.
$this->db->escape()
è una funzione che determina il tipo di dato trattato e permette di operare l'escape soltanto dei dati stringa, inoltre, essa è in grado di aggiungere singoli apici evitando che questa incombenza sia a carico dell'utilizzatore:
$query = "INSERT INTO tabella (testo) VALUES(".$this->db->escape($testo).")";
$this->db->escape_str()
è invece una funzione che effettua l'escape delle informazioni passate come parametri indipendentemente dal tipo di dato:
$query = "INSERT INTO tabella (testo) VALUES('".$this->db->escape_str($testo)."')";
Per le sue caratteristiche peculiari questa seconda funzione è però molto meno utilizzata rispetto alla prima.
Un altro aspetto importante delle query eseguite attraverso gli strumenti messi a disposizione da CodeIgniter è quello relativo al Query Bindings, una procedura ideata appositamente per semplificare la scrittura delle interrogazioni in sede di sviluppo; il framework non fornisce delle particolari funzioni per il Query Bindings, è invece sufficiente l'utilizzo associato della funzione $this->db->query
e del punto interrogativo; analizziamo il seguente esempio:
$query = "SELECT * FROM tabella WHERE id = ? AND titolo = ? AND autore = ?"; $this->db->query($query, array(12, 'La Divina Commedia', 'Dante Alighieri'));
I punti di domanda presenti all'interno dell'interrogazione vengono automaticamente rimpiazzati con i valori contenuti nel secondo parametro passato sotto forma di array alla funzione $this->db->query
.
Uno dei vantaggi derivanti dal Query Bindings sta nel fatto che i valori coinvolti all'interno delle interrogazioni non devono essere sottoposti manualmente a operazioni di escape dei dati, il framework sarà in grado di effettuarle del tutto autonomamente.
Generare i risultati delle query
Analizziamo la seguente sequenza di codice:
$query = $this->db->query("SELECT nickname,email,data FROM agenda WHERE Id = 1"); $row = $query->row(); echo $row->nickname; echo $row->email; echo $row->data;
row()
è una funzione che restituisce come risultato un singolo record (fornito sotto forma di oggetto), se la query prevede l'estrazione di più di un record verrà restituita soltanto la prima riga.
Se si desidera produrre più di un risultato è possibile utilizzare un diverso costrutto:
$query = $this->db->query("SELECT titolo,testo,autore FROM libri ORDER BY Id DESC"); foreach ($query->result() as $row) { echo $row->titolo; echo $row->testo; echo $row->autore; }
Nel nostro secondo esempio, alla base dell'estrazione dei dati vi è la funzione result()
che se eseguita con successo restituisce un array di oggetti da "ciclare" attraverso un costrutto PHP per l'iterazione come foreach
, in caso di fallimento produce invece un array vuoto.
Naturalmente sarà possibile sottoporre i risultati delle query ad un semplice controllo basato su condizione:
$query = $this->db->query("SELECT nome,cognome,indirizzo FROM recapiti ORDER BY nome ASC"); if ($query->num_rows() > 0) { foreach ($query->result() as $row) { echo $row->nome; echo $row->cognome; echo $row->indirizzo; } }
num_rows()
è una funzione che svolge un compito identico a quello di mysql_num_rows()
, controlla quindi il numero di valori contenuti all'interno dell'array prodotto dalla query; nel nostro esempio in caso di array vuoto non verrà prodotto alcun output.
Conclusioni
In questa trattazione abbiamo affrontato brevemente il discorso relativo all'interazione tra il framework CodeIgniter e le basi di dati; per far questo sono stati affrontati i principali aspetti relativi all'argomento tra cui: le procedure per la configurazione, le metodologie per la connessione con il Database server, gli strumenti a disposizione per l'esecuzione delle interrogazioni e per la generazione dei risultati.
L'argomento, molto vasto, potrebbe essere ripreso in seguito per la trattazione di aspetti più specifici, nell'attesa si consiglia di consultare l'ottima sezione dedicata alle relazioni con i database presente nel Wiki di CodeIgniter.