Introduzione
1. Vantaggi, requisiti e installazione
La prima applicazione
2. 3. 4. 5. 6. 7. Creare una web application Struttura dell'applicazione Yii Yii in azione: il file index.php I file di configurazione Url seo friendly Modulo Gii
Pattern MVC
8. Controller 9. Viste 10. Introduzione a CActiveRecord 11. Le operazioni CRUD: update ed insert 12. Le operazioni CRUD: select e delete 13. Metodi utili, scope e relazioni
Esempi di programmazione
14. 15. 16. 17. 18. 19. Creare un form: la classe CFormModel Creare un form: raccogliere i dati Gestire il database Autenticazione degli utenti Component e modules Conclusioni
Vantaggi di Yii
Ci sono svariati motivi per scegliere Yii rispetto a framework pi conosciuti e blasonati. Yii implementa in modo superbo il pattern MVC. Come vedremo nel corso di questa guida, le definizioni di models, controllers e viste sono operazioni facili da realizzare anche grazie all'ausilio di un apposito modulo. La documentazione di Yii eccezionale . Il tutorial iniziale fornisce tutte le informazioni per diventare sin da subito padroni del framework. Oltre alla guida introduttiva, ben fatta anche la documentazione delle API che risulta facile da utilizzare, ben scritta e soprattutto completa. Le informazioni su Yii non finiscono qui. Esistono svariati tutorial ed estensioni ben documentate. A completare il tutto una community sempre pronta e preparata per venirvi in soccorso sia in lingua italiana che, pi numerosa, in lingua inglese. Yii completo. Nel framework, grazie anche alle estensioni, sono presenti tutti gli strumenti necessari alla realizzazione di una web application complessa.
Requisiti e installazione
Ma partiamo subito: scarichiamo Yii e creiamo la nostra prima applicazione . Per scaricare l'ultima versione del framework sufficiente collegarsi alla pagina di download ufficiale e procurarsi l'archivio tar.gz o zip. C da precisare che, scorrendo ancora la pagina, si nota la possibilit di scaricare Yii da un archivio svn in modo da poterlo aggiornare pi facilmente. Questo metodo, per quanto allettante, presenta delle complicazioni. Sappiate innanzitutto che possibile posizionare la cartella contenente il framework allesterno del dominio su cui lavoriamo. Questa opzione particolarmente interessante per aziende, ma anche liberi professionisti, che realizzano il grosso del lavoro sfruttando Yii e che posseggono un server dedicato. In questo modo infatti, effettuando un banale update della copia locale del repositore, si aggiornano tutte le applicazioni simultaneamente. Qui viene la nota dolente. A volte le modifiche apportate dagli sviluppatori sono tali che le nuove versioni del framework rendono instabili le applicazioni. Il consiglio quindi quello di effettuare lupdate del framework su un server di prova e verificare che tutto funzioni perfettamente. Tornando allinstallazione del framework, va detto che la versione 1.1 compatibile con le versioni di PHP maggiori o uguali alla 5.1. Per quanto riguarda i database supportati ci sono, visto che lavoriamo in ambiente LAMP, sia MySql sia SqlLite.
Una volta decompresso il file, che pesa poco pi di 4 MB, spostate il contenuto della cartella che vi inclusa in una directory del vostro server. Troverete la root del sito con una struttura uguale alla seguente
Puntando il browser alla cartella Requirements del sito, comparir una schermata in cui sar indicato il soddisfacimento dei requisiti per installare Yii (figura 1). Figura 1: schermata di riepilogo dei requisiti di sistema
Come si vede, nel nostro caso, non ci sono impedimenti allutilizzo di Yii. Ci sono esclusivamente dei warning che indicano che per determinate funzionalit devo abilitare alcune estensioni di PHP. Possiamo ignorarle e passare avanti.
Dove path_yii il percorso della cartella in cui avete scaricato Yii e app il nome dell'applicazione che vogliamo installare. Esempio: yiic.bat webapp C:\xampp\htdocs\myapp. Questo comando funzioner se avete nel percorso di sistema l'eseguibile locale di php. Se cos Windows (o Linux) visualizzeranno un errore di file non trovato e a noi toccher indicare il percorso completo del file stesso. Posizioniamoci nella cartella in cui avete caricato i file di Yii ed eseguite il comando:
e:/wp/php framework/yiic.php webapp path_yii/app
Dove al posto di e:wp/php dovrete indicare il percorso al file eseguibile di PHP e al posto di path_yii/app il percorso della cartella in cui volete creare l'applicazione. Esempio: C:\xampp\php\php.exe C:\xampp\htdocs\yii\framework\yiic.php webapp C:\xampp\htdocs\myapp. Se siete utenti Linux potreste avere la necessit di impostare i permessi sulle seguenti cartelle:
I permessi servono per consentire al modulo gii, di cui parleremo pi avanti nella guida, di operare in quelle cartelle. In fase di creazione della nostra applicazione abbiamo indicato come percorso (path_yii) quello in cui erano presenti i file del framework creando una cartella ( app) al suo interno. La scelta motivata dal fatto che, essendo questa una guida al framework, preferibile che tutti i file si trovino nello stesso percorso. Nella pratica possibile creare la nostra applicazione in una qualsiasi posizione del nostro server web.
Quest'ultima situazione molto utile qualora si intendano sviluppare numerose applicazioni con Yii e si disponga di un server dedicato. Il vantaggio maggiore dato dalla possibilit di aggiornare il framework per tutte le nostre applicazioni in un colpo solo. Non dimentichiamoci infatti, che Yii sotto controllo di versione. Di conseguenza laggiornamento pu essere realizzato semplicemente facendo un update della nostra copia locale. opportuno, come abbiamo indicato gi in precedenza, prima di eseguire unazione del genere sul server di produzione, di effettuare un test su un server di prova di tutte le applicazioni interessate dallupdate. Dopo tanta fatica giunto il momento di visualizzare la home page della nostra applicazione. Aprite il browser e puntate alla cartella http://localhost/app in cui installata la nostra applicazione. Figura 2: schermata principale di una web application
Come si vede nella figura sopra la pagina di benvenuto ci fornisce alcune informazioni su come modificare laspetto della home-page.
//contiene file pubblicati in precedenza //contiene i fogli di stile //contiene le nostre immagini //contiene i temi dellapplicazione //contiene i file protetti dellapplicazione
yiic
yiic.bat yiic.php commands/ shell/
consolle
components/ Controller.php UserIdentity.php config/ console.php main.php test.php controllers/ SiteController.php data/ //contiene i componenti //la classe base del controller //classe usata per lautenticazione //contiene i file di configurazione //file di configurazione per le applicazioni consolle //file di configurazione per le applicazioni web //file di configurazione per le unit di test //contiene le classi controller //il controller di default dellapplicazione //dati di esempio del database
schema.mysql.sql schema.sqlite.sql
testdrive.db extensions/ messages/ models/ LoginForm.php ContactForm.php runtime/ tests/ views/
layouts/ main.php column1.php column2.php site/ pages/ about.php contact.php error.php index.php login.php
//contiene il layout //il layout condiviso da tutte le pagine //layout a singola colonna //layout a doppia colonna //vista per il controllo site //contiene pagine statiche //vista della pagina about
//la vista della pagina contatti //la vista degli errori //la vista della pagina index //la vista per laction login
Ricordo che queste cartelle sono situate allinterno della directory della nostra applicazione poich in fase di creazione abbiamo scelto questa soluzione. Si veda il paragrafo installazione per ulteriori chiarimenti.
Path e alias
Yii dispone di una serie di alias che ci consentono facilmente di puntare alle cartelle con pochi comandi. In unapplicazione Yii ci sono delle cartelle ritenute fondamentali ed proprio su di esse che sono definiti gli alias. Esistono 5 alias predefiniti che sono:
System: la directory principale del framework, framework appunto Zii: si riferisce alla directory zii di cui parleremo pi avanti Application: si riferisce alla directory protected Webroot: si riferisce alla cartella in cui abbiamo creato lapplicazione Ext: la cartella extensions
Da questo punto in poi possibile utilizzare tutti i metodi che la classe mette a disposizione. Il metodo che ci interessa in questo momento getPathOfAlias.
verr visualizzato il percorso della nostra applicazione. Conoscere questi percorsi molto utile quando bisogna importare i file allinterno dei nostri script. possibile invece definire gli alias personalizzati utilizzando il metodo setPathOfAlias nel seguente modo:
Yii::setPathOfAlias('mioAlias',$path);
dove $path pu essere ricavato con lausilio del metodo getPathOfAlias. Ad esempio, per la cartella test situata nella root della nostra applicazione, potremmo scrivere in questo modo :
$testPath = Yii::getPathOfAlias('webroot')."/test"; Yii::setPathOfAlias('test', $testPath); echo Yii::getPathOfAlias('test');
Comando che visualizzer, nel nostro caso, D:/www5/yii/app/test. All'interno della guida faremo spesso riferimento agli alias per indicare la posizione dei file che ci interessano. Yii ci viene in soccorso anche in questo con una banalissima funzione:
Yii::import('alias');
Partendo da un alias possibile quindi importare qualsiasi file. Le cartelle allinterno di quelle definite dallalias, vengono concatenate allalias mediante il punto. Quindi utilizzando lalias appena creato:
Yii::import('test.*'); $t = new test();
Con la sintassi appena indicata importiamo quindi tutte le classi che sono contenute nella cartella test. Il vantaggio di utilizzare il metodo import fornito da Yii, invece di require o include, che in questo modo il file viene incluso se, e solo se, viene istanziata la classe. chiaro che utilizzando una sintassi del genere per tutte le nostre classi personali, non dobbiamo preoccuparci di includerle dove servono. Ci penser Yii a farlo per noi senza correre il rischio di includere file inutili.
I file di configurazione
Prima di continuare ad addentrarci nel mondo di Yii dobbiamo fermarci qualche attimo ad analizzare il file di configurazione. Yii dispone di tre file di configurazione, tutti situati nella cartella app/protected/config/. Essi sono:
console.php File di configurazione per le applicazioni console main.php File di configurazione per le web application test.php File di configurazione per le unit test
In questa guida ci occuperemo esclusivamente del file main.php, ma i concetti esposti per esso valgono grosso modo anche per gli altri due file. Da notare, inoltre, che nel file di configurazione si fa riferimento a cose non ancora trattate nella guida come ad esempio i moduli. Il file di configurazione main.php di Yii non altro che un grande array associativo. Ad ogni indice pu corrispondere un singolo valore oppure un array associativo. Vi suggerisco, per seguire questa parte della guida, di aprire il file in un editor PHP in modo da individuare facilmente quello di cui parliamo. Si far sempre riferimento alle chiavi per spiegarne il significato.
Funzione Chiave basePath => Indica il path di base. Normalmente si lascia inalterato. Il nome della vostra applicazione. Visualizzato nella home ma soprattutto nel titolo name => delle pagine. preload => Un array che indica quali sono i componenti da precaricare. Un array che ci indica cosa deve essere caricato automaticamente. Nel file di esempio import => sono auto caricati i model e i component. modules => Si tratta di un array che indica quali moduli devono essere caricati insieme ad Yii. Costituito da un array associativo nella forma chiave valore. Consente di accedere al Params => valore di ogni singola chiave mediante larray associativo params della classe app.
Soffermiamoci sulla chiave modules. Ogni modulo caricato rappresenta un indice di modules mentre il valore di questo indice un array. Gli indici dellarray dei valori possono cambiare a secondo del modulo che si desidera caricare. Nel file di configurazione di esempio vanno decommentate le linee per caricare il modulo gii, funzione in grado di rendere automatica la generazione di alcuni tipi di codice. Non dimentichiamoci di modificare le voci password e, se serve, ipFilters che indicano, rispettivamente, la password da usare per accedere alle funzioni del modulo Gii e il range di indirizzi IP accettati per l'accesso al modulo.
'modules'=>array( // uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'system.gii.GiiModule', 'password'=>'password-a-scelta', // If removed, Gii defaults to localhost only. Edit carefully to taste. 'ipFilters'=>array('127.0.0.1','::1'), ), ),
Decommentate anche url manager, in modo da rendere le url seo friendly, e db, in modo da poter lavorare con il database. Nel file di esempio ufficiale decommentato il modulo db riferito ad un database SQLite. Per chi volesse utilizzare, come noi, un database MySql basta commentare la voce relativa a SQLite e decommentare quella relativa a MySql sostituendo i dati di esempio con quelli della vostra configurazione (nel codice sotto miodb, mioutente e miapassword).
/*'db'=>array( 'connectionString' => 'sqlite:'.dirname(__FILE__).'/../data/testdrive.db', ),*/ 'db'=>array( 'connectionString' => 'mysql:host=localhost;dbname=miodb', 'emulatePrepare' => true, 'username' => 'mioutente', 'password' => 'miapassword', 'charset' => 'utf8', ),
Infine troviamo errorHandler,che indica quale controller/action deve essere richiamato in caso di errore, e log, che indica quale classe di occupa del log dell'applicazione.
Il menu offerto da Yii presenta negli uri la pagina index.php. Se abbiamo scelto di avere gli uri seo friendly appare evidente che possibile eliminare dagli uri del nostro sito il valore index.php e lasciare che sia il Web server a decidere che tipo di pagina servire. Per evitare che nei nostri uri compaia index.php, possiamo seguire due strade. Poich il menu di Yii viene realizzato mediante un widget, di cui parleremo pi avanti nella guida, la soluzione ottimale sarebbe quella di modificare il widget. La pi semplice invece quella di modificare la vista nella quale contenuto il menu. Per vista di intende un file PHP in cui normalmente viene inserito il codice che viene visualizzato nel browser. Parleremo in seguito delle viste. Il file che bisogna modificare il seguente: protected/views/layout/main.php Per ottenere ci che vogliamo sufficiente che la riga
array('label'=>'Home', 'url'=>array('/site/index')),
divenga
array('label'=>'Home', 'url'=>array('../site/index')),
Modulo Gii
Prima di entrare nel dettaglio dellutilit del modulo gii, creiamo con phpmyadmin un database e una semplice tabella user che abbia come campi il nome utente, la password, la mail e la data di iscrizione.
CREATE TABLE tbl_user ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, username VARCHAR(128) NOT NULL, password VARCHAR(128) NOT NULL, email VARCHAR(128) NOT NULL );
Il modulo gii consente di creare, partendo solo dal nome di una tabella nel database, il model, il controller e le viste necessarie per effettuare le operazioni CRUD (create, read, update and delete) su quella tabella. Per utilizzarlo digitate http://localhost/app/index.php/gii e inserite la password specificata nel file di configurazione. Vi troverete in una schermata come quella mostrata sotto. Figura 3: Il modulo gii e le sue funzioni
A questo punto cliccate su Model Generator e inserire il nome della tabella nel rispettivo campo. Noterete immediatamente che il campo Model Name si auto-compone. In realt il nome del model corrisponder sempre al nome della tabella nella notazione camel. Selezionare il box per la
generazione delle relazioni, che devono essere implementate nel database, e cliccate su Preview . Se inserite un nome di tabella non valido riceverete un messaggio di errore ma, in caso contrario, vi verr mostrato il nome del file che verr generato. Noterete subito che comparir la voce New nella colonna generate. Difatti possibile ricreare il model qualora il file sia gi esistente seguendo la stessa procedura. In quel caso verranno mostrate, se ci sono, le differenze tra il file esistente e quello generato da gii. Selezionando o meno il Box, avrete la possibilit di sovrascrivere il file. Lo stesso discorso vale per tutti i file generati mediante il modulo gii.
Prima di cliccare su generate copiate il nome del model per non dimenticarlo. A questo punto abbiamo il nostro model, ma mancano le viste e il controller. possibile generare i file singolarmente ma, cliccando sul link Crud Generator possiamo svolgere le operazioni simultaneamente. Inserendo nel primo campo il nome del model User, il campo relativo al controller si auto compone. Cliccate prima su Preview e poi su Generate per completare loperazione.
A questo punto digitate nella barra degli indirizzi http://localhost/app/index.php/user e magicamente vi ritroverete nella pagina che ci consente di gestire gli utenti. Le operazioni CRUD sono normalmente abilitate ai soli amministratori del sito. Il modulo gii tiene conto di questa cosa pertanto, per inserire o modificare un utente, necessario essere loggati. Al momento potete effettuare laccesso con admin/admin che sono i valori di default di Yii. Parleremo pi avanti di autenticazione e gestione dei permessi. Senza scendere nel dettaglio di quello che offre Yii, possiamo affermare che in pochi passaggi siamo riusciti a creare un sistema per le operazioni CRUD su una tabella del database. Molti di voi si staranno fregando le mani al pensiero di fare con due click interi siti dinamici. In teoria cos ma nella pratica bisogna personalizzare i vari elementi, cio model, controller e viste, per rendere il sito professionale. Come avrete modo di notare infatti tutte le form generate da Yii avranno dei semplici campi di testo. Sar compito del programmatore sostituire tali elementi del form con quelli pi idonei.
Controller
A questo punto giunto il momento di analizzare come Yii implementa il pattern MVC ModelView-Controller. Analizzeremo quindi il controller, le viste e per finire i model. Questi oggetti rappresentano il cuore della nostra applicazione. Nella lezione precedente abbiamo creato, mediante il modulo gii, il controller, le viste e il model necessari alla gestione della tabella user del database. Per spiegare il funzionamento del pattern MVC in Yii faremo riferimento a questi file. Prima di proseguire bene che sappiate che in questi paragrafi si da per scontato che sappiate cosa si intende per pattern MVC e del suo funzionamento.
Controller
Cominciamo col dire che tutti i controller si trovano nella cartella application.controllers ( un alias) ed hanno un nome che composto generalmente dal nome del model pi il suffisso
controller, sempre nel formato camel. Come noterete, per raggiungere un controller, sufficiente digitare nella barra degli indirizzi www.miohost.com/miocontroller: quindi il nome, tutto in minuscolo, senza il suffisso controller. Sar compito di Yii in base all url, stabilire quali file richiamare. Preciso che possiamo usare lurl precedente solo se abbiamo configurato correttamente il file di configurazione main.php e modificato il file .htaccess come spiegato nelle lezioni precedenti. Qualora non abbiate configurato il file .htaccess, luri precedente diventa: www.miohost.com/index.php/miocontroller. Aprendo il file UserController.php noteremo immediatamente che il controller una classe che estende la classe base Controller. Ogni controller dotato di una serie di azioni che altro non sono che un insieme di metodi il cui nome ha il prefisso action. Le azioni possono essere richiamate aggiungendo alluri precedente /nomeAzione ovviamente senza il prefisso action e senza virgolette. Qualora alluri non venga passata nessuna azione, il controller esegue lazione predefinita che generalmente index. Questo comportamento pu essere modificato settando la propriet defaultAction ad un valore diverso.
public $defaultAction = "nuovaAzionePredefinita";
In Yii il nome del controller, cos come quello delle azioni, rappresenta quindi lidentificativo di tali elementi. Per cui potremmo dire che per richiamare un'azione di un controller basta aggiungere alluri di base IDController/IDAzione. Qualora Yii non riesca ad individuare un controller, o un'azione, con lid passato nella uri, verr mostrato a video il classico errore 404. Lo scopo ultimo del controller quello di rendere una vista allutente finale, magari a seguito di un elaborazione di dati forniti dallo stesso. Yii consente di ricevere i parametri passati mediante GET in una action, semplicemente passandoli come parametri del metodo stesso. Ad esempio se volessimo passare user e password al metodo login del controller user, dovremmo scrivere lurl nel seguente modo: www.miohost.com/user/?user=ciro&password=test. Il metodo login quindi avrebbe la seguente firma
public function actionLogin($user, $password<u>)</u>
possibile passare un valore di default ai parametri. Questo serve ad evitare un errore 400 qualora si ometta di passare il parametro mediante GET. I parametri dellaction possono essere anche degli array. In tal caso la firma diverrebbe:
public function actionMetodo(<strong>array</strong> $campo<u>)</u>
Fino ad ora abbiamo considerato le azioni solo come metodi del nostro controller. Yii mette a disposizione un sistema mediante il quale possibile definire le azioni come metodi di una classe
esterna. La prima cosa da fare quella di effettuare un override del metodo actions in esso si definisce un array che contiene linsieme della azioni personalizzate. Larray di tipo associativo e in esso la chiave rappresenta lidentificativo dellazione, nel nostro caso login, mentre il valore della chiave indica il path al file che contiene la definizione dellazione stessa.
public function actions() { return array( 'login'=> 'application.components.login' ); }
login
rappresenta una classe che estende la classe base actions ed ha un unico metodo chiamato
In base a quanto detto il codice appena sopra va inserito in un file login.php nella cartella components. Di notevole importanza il metodo filters. Questo metodo, che il primo generato dal modulo gii per il controller user, consente di eseguire azioni prima e dopo la action del controller . Un esempio molto semplice proprio quello che troviamo nel controller User: in esso filters restituisce accessControl. Quest'ultimo un componente di Yii che in base a determinate regole, definite in questo caso nel metodo accessRule, consente di stabilire se un utente ha o meno i permessi di eseguire una determinata azione. Come si vede da UserController il metodo accessRule abbastanza semplice. Si tratta di un array formato da array. Ognuno di essi ha tre elementi :
actions: non obbligatorio ma se presente il suo valore un array con gli id delle azioni user: indica a quale utente deve essere applicata la regola e pu assumere i seguenti valori
o o o
Altri due metodi interessanti del controller di esempio sono loadModel e performAjaxValidation. I due metodi hanno nomi abbastanza intuitivi ad ogni modo il primo consente di caricare il model in base ad un determinato id mentre il secondo effettua la validazione ajax del form user. Al momento queste cose potrebbero non esservi chiare. Chiariremo il tutto quando parleremo del model. Inoltre ritorneremo a parlare dei controller e dei suoi metodi anche quando parleremo delle viste.
Viste
Le viste rappresentano la parte pi semplice del pattern MVC. Si tratta di semplici file PHP in cui, mediante del normalissimo codice HTML, viene mostrato loutput allutente finale. Ovviamente, nel caso di pagine dinamiche, avremo pezzi di codice PHP. La quantit di codice PHP deve essere ridotta al minimo questo per applicare alla regola il pattern MVC. Prima di vedere come si passano dati alle viste bene soffermarci un attimo sulla nomenclatura. Le viste si trovano nella posizione application.views (alias). All'interno di questa cartella sono presenti ulteriori cartelle ognuna delle quali rappresenta un gruppo di file. L'insieme di questi file forma le viste per un determinato controller . Il nome di queste cartelle corrisponde allid del controller con la prima lettera minuscola. Nel nostro caso, riferendoci al controller user, le viste che ci interessano sono quelle situate sotto la cartella user. A questo punto si potrebbe pensare che un controller pu renderizzare esclusivamente le proprie viste. Anche se questa la prassi consigliata, possibile renderizzare le viste di un altro controller. Scorgendo lalbero dell'applicazione vi sarete resi conto che sotto la cartella views presente una cartella chiamata layouts. Intuirete che questa cartella costituisce il template della nostra applicazione. Prima di soffermarci su di essa per, dobbiamo chiarire ancora come visualizzare una vista e come passargli dei valori. Loperazione di renderizzazione di una vista avviene allinterno dei singolo controller. Il metodo che ci consente di effettuare questa operazione il metodo render. Questo metodo ha tre argomenti:
Nome della vista: indica il nome del file fisico da caricare senza lestensione PHP. Normalmente il file viene ricercato sotto la cartella views/idController. Nel caso quindi del controller user views/user/nomeDellaVista Parametri: un array associativo.
Return (booleano): se questo parametro impostato su true la vista non viene mostrata a video ma viene restituita come stringa. In questo caso quindi il metodo render ha un valore di ritorno di tipo stringa. Tuttavia il valore di default impostato a false e quindi la vista viene visualizzata.
Per quanto riguarda i parametri si tratta appunto dei dati variabili che possono essere renderizzate nelle viste semplicemente leggendone i valori. Ad esempio se allinterno di una delle azioni del nostro controller user scriviamo una cosa del genere:
$parametri = array('oggi'=>date("d-m-Y")); $this->render('index',$parametri);
visualizzeremo a video il contenuto del file index.php che si trova nella cartella views/user. Inoltre inserendo nella vista il seguente codice:
<?php echo $oggi; ?>
Questo codice stamper quindi la data odierna. Come si nota il nome della variabile corrisponde alla chiave dellarray parametri. facile intuire che in questo modo possiamo visualizzare nella vista tutti i dati che vogliamo. Richiamare il metodo render vuol dire mostrare, allinterno del template del sito, il contenuto di una vista. Il template del sito viene realizzato mediante i file che sono presenti nella cartella views/layout. Facendo riferimento al controller user, si nota la presenza del seguente codice:
public $layout='//layouts/column2';
questo codice indica ad Yii che deve utilizzare, per la visualizzazione delle nostre pagine, il file column2.php che si trova ovviamente sotto la vista layouts del sito. possibile modificare questa propriet in ogni controller, in modo da personalizzare il template. A questo punto guardiamo pi da vicino la vista layouts che contiene informazioni molto importanti. Come abbiamo accennato in precedenza questa vista rappresenta, insieme ai fogli di stile, il template della nostra applicazione. Scendendo ancora di pi nel dettaglio possiamo affermare che oltre al file main anche i file column1.php, e column2.php contribuiscono alla realizzazione del template. Abbiamo appena detto infatti che modificando la propriet layout del nostro controller, possiamo scegliere quale dei due file utilizzare tra column1 e column2. Se analizziamo entrambi i file ci rendiamo conto che allinizio e alla fine di ognuno troviamo il seguente codice:
<?php $this->beginContent('//layouts/main'); ?>
e
<?php $this->endContent(); ?>
Questo codice, che va inserito in ogni file che vogliamo usare come template, come ad esempio una struttura a tre colonne, effettua il render della pagina main sempre della vista layouts. $this invece rappresenta listanza del controller che invoca la vista.
Bisogna assolutamente che ricordiate questa cosa. Infatti allinterno delle viste potranno essere renderizzati dei widget, di cui discuteremo pi avanti, mediante listanza del controller. In merito i widget al momento ci interessa sapere che sono strumenti che ci aiutano a realizzare porzioni di codice anche complesse. Nel file main.php si utilizza un widget per la realizzazione del menu in alto. Come si vede ogni elemento del menu un array in cui c la label e lurl. Dando un rapido sguardo al file main, ci si rende conto che in un punto del codice presente:
<?php echo $content; ?>
In questa posizione verr inserito il contenuto del file definito nella propriet layout del controller. Nel nostro caso quindi verr visualizzato il contenuto del file column2. Sempre guardando il file main troviamo il seguente codice:
Yii::<em>app</em>()->request->baseUrl;
come si intuisce esso fornisce luri di base della nostra applicazione. Infatti viene utilizzato per caricare i css e i javascript che intendiamo adoperare nell'applicazione. Nel Tag title della pagina troviamo
CHtml::<em>encode</em>($this->pageTitle);
Il valore della propriet $this->pageTitle fornisce il titolo della nostra pagina che Yii comporr automaticamente, mentre il metodo statico CHtml::encode, parte di una classe helper di Yii, trasforma i caratteri speciali in entit HTML Molto interessante la propriet Yii::app()->user->isGuest che ci dice infatti se lutente un guest o un utente registrato. Sfruttando questa propriet, insieme allattributo visible del menu, possibile quindi visualizzare o meno una voce del menu a secondo se si tratta di un utente registrato o meno. Per finire il seguente pezzo di codice
<?php if(isset($this->breadcrumbs)):?> <?php $this->widget('zii.widgets.CBreadcrumbs', array( 'links'=>$this->breadcrumbs, )); ?><!-- breadcrumbs --> <?php endif?>
Visualizza il bradcrumbs. Per concludere il discorso delle viste dobbiamo parlare del metodo renderPartial. Come intuirete dal nome questo metodo effettua una renderizzazione parziale di una vista. Cosa vuol dire? Che, a differenza del metodo render, il file main, ed eventualmente il file dichiarato nella propriet layout, non vengono renderizzati. Solo il contenuto del file richiamato dal metodo processato e mostrato. Questo sistema risulta particolarmente utile quando ci sono porzioni di codice comuni a pi viste. Il metodo dispone di quattro argomenti. Oltre a quelli del metodo render disponibile $processOutput. Questo parametro se impostato a true processa gli script allinterno della vista. In poche parole se ci sono javascript allinterno del codice questi vengono processati.
Introduzione a CActiveRecord
Come sappiamo uno degli aspetti principali di una web application lutilizzo di una base di dati. Yii ci consente di interagire con differenti tipi di database: MySql, MsSql, Oracle ecc.. Lutilizzo di una base di dati invece che unaltra, avviene in modo del tutto trasparente per lutente . Yii infatti, utilizza la libreria PDO di PHP per interagire con i dati. Quindi indipendentemente dalla base di dati, il model, presenter sempre i medesimi metodi che ci consentiranno di interagire con una tabella del nostro database. Prima di addentrarci nel vero utilizzo di active record bene ricordare che deve essere definita, allinterno del file di configurazione, una connessione al database. Infatti, anche se avviene in modo del tutto trasparente allutente, il model far uso di quella connessione. Come al solito utilizziamo il file di esempio che abbiamo creato inizialmente mediante il modulo gii. I model si trovano appunto nella posizione application.models. La prima cosa che possiamo notare, e che avevamo gi anticipato, che il model una classe che estende CActiveRecord il cui nome rappresentato dal nome della tabella alla quale relazionato nel formato camel. Il nome del file corrisponde al nome della classe. In realt possibile utilizzare per la classe, e quindi anche per il nome del file, nomi diversi rispetto alla tabella. Potrebbe tornare utile quando in un database, abbiamo delle tabelle , raggruppate secondo una certa logica, mediante un prefisso. In questo caso , almeno di omonimie, si potrebbe preferire di utilizzare un nome senza prefisso. Se scegliamo questa strada dobbiamo per dire al model a quale tabella ci riferiamo mediante loverride del metodo tableName
public function tableName() { return "nomeDellaTabella"; }
Nel costruttore del nostro model c solamente un richiamo al costruttore padre, al quale viene passato il nome della nostra classe. Il primo metodo interessante senza dubbio attributeLabels() che pubblico. Come potete facilmente intuire questo metodo fornisce le etichette dei campi della nostra tabella . Probabilmente quando abbiamo progettato il database, abbiamo utilizzato per i campi nomi composti legati tra loro mediante il simbolo dellunderscore. Se lato database la cosa funzionale lo molto meno quando si tratta di presentare il contenuto allutente. Questo metodo ci consente, mediante un array di tipo associativo, di collegare ad ogni campo della tabella una etichetta. Uno dei metodi pi importanti allinterno del nostro model rules(). Prima di scendere nel dettaglio dobbiamo comprendere cosa si intende per scenario. In modo abbastanza grossolano, possiamo dire che uno scenario indica le iterazioni che intercorrono tra lutente e il sistema. Uno scenario pu essere pensato appunto come una serie di azioni che portano ad un determinato stato del sistema. Si immagini loperazione di inserimento di un nuovo utente. Ci sono varie fasi(sintetizzando):
Presentazione della schermata di inserimento Ricezione, valutazione e memorizzazione eventuale dei dati Messaggio di risposta allutente
Quello appena descritto potrebbe rappresentare lo scenario di inserimento. Fatta questa premessa, capire il funzionamento del metodo rules diviene semplice. Questo metodo restituisce un array di array. Ogni singolo array presenta determinati valori. Il primo tra questi la lista dei campi, separati con la virgola, della tabella a cui deve essere applicata la regola. Successivamente troviamo il validatore, che costituisce di fatto la vera regola che sar applicata ai campi e, per finire, lo scenario sottoforma di chiave => valore. La chiave sempre on. La documentazione ufficiale sicuramente di grande aiuto nel fornire tutti i possibili valori per le regole da applicare. In questa guida diciamo solo che il validatore pu essere:
Un alias (boolean, email, requier, ecc),di significato immediato, delle classi di validazione. Il nome di una classe che estende la classe CValidator. Il nome di un metodo del nostro model.
Qualora ad uno stesso campo si debbano applicare pi di una regola, sufficiente creare tanti array per quante regole occorrono.
public function rules() { return array( array('id', 'required', 'on'=>'update'), array('id', 'numerical', 'integerOnly'=>true), array('user, password, mail', 'length', 'max'=>255), array('data_iscrizione', 'safe'), array('id, user, password, mail, data_iscrizione', 'safe', on'=>'search'), ); }
Nel nostro caso, il campo id, oltre ad essere obbligatorio, nello scenario update, deve essere necessariamente un numero e la lunghezza massima consentita per i campi user, password e mail 255 caratteri. Queste informazioni son state generate mediante il modulo gii. Nulla ci vieta di modificarle a nostro piacimento. Il modulo gii preleva le informazioni del metodo rules, come ad esempio la chiave primaria, la lunghezza e lobbligatoriet dei campi, dallinterno dello schema della tabella. Se modifichiamo lo schema della tabella dobbiamo ricordarci quindi di apportare le necessarie modifiche al model, onde evitare errori inaspettati. Uno dei metodi pi semplici per aggiornare il model quello di chiedere a gii di rigenerare il model stesso. Prima di creare fisicamente il file ci mostrer le differenze con il file che abbiamo. A quel punto ci baster intervenire per le eventuali correzioni sul nostro model. Qualora le modifiche allo schema siano minime il consiglio quello di non passare dal modulo gii ma di apportare le modifiche in modo manuale. Interessante invece l'ultimo caso quello dello scenario search. In quel caso gli attributi vengono definiti sicuri , safe appunto, per poterli utilizzare. Un attributo non definito in questa regola non pu essere utilizzato per la ricerca.
giunto il momento di entrare nel cuore di active record. In poche parole vediamo ora come possibile effettuare le operazioni CRUD sfruttando il nostro model. Cominciamo col dire che ogni singolo campo della tabella rappresentato nel nostro model da una propriet. Inserire un record nella tabella quindi estremamente semplice. Nel nostro caso basta il seguente codice:
$usr = new User(); $usr->user = 'User'; $usr->password = 'Password'; $usr->mail = 'Mail'; $usr->data_iscrizione = '2012-05-22'; $usr->save();
Vi ricordo che il model viene istanziato prevalentemente allinterno del controller. Quindi il codice va riportato in una action del controller stesso. Come si vede, non si fa altro che assegnare ad ogni singolo attributo, che ha lequivalente campo nella tabella, un valore. Successivamente si richiama il metodo save per memorizzare i dati nella tabella. Il metodo save effettua la validazione sui campi. Una volta inserito il record possibile recuperare lid semplicemente leggendo il valore della propriet dellid. Nel nostro caso appunto
$usr->id
Per indicare ad Yii che si vuole utilizzare una funzione nativa del database come valore del campo, si ha la necessit di ricorrere ad una classe ausiliare. La classe in questione CDbExpression.
$user->data_iscrizione = new CDbExpression('now()');
In questo caso Yii avvisato di mettere il contenuto passato come parametro, direttamente nella query Sql. Ovviamente ci sono alcune funzioni del database che richiedono dei parametri. In Yii stato pensato anche questo.
$usr->password = new CDbExpression('md5(:pwd)', array(":pwd"=>"test"));
Il primo parametro la funzione che vogliamo richiamare con allinterno i parametri nel formato :nome parametro - i due punti fanno parte della sintassi Il secondo parametro la lista dei parametri sotto forma di array associativo nel quale, la chiave corrisponde al parametro, sempre con i due punti, e il valore il valore che vogliamo passare. Il metodo save restituisce come valore di ritorno un valore booleano . In caso di successo restituisce true mentre in caso contrario restituisce ovviamente false. Testando il metodo save possibile stabilire se linserimento andato a buon fine. Qualora qualcosa vada storto, probabile che uno dei campi non sia validato. Linsieme degli errori degli attributi inserito allinterno di un array che si ottiene richiamando il metodo getErrors. Se si desidera ottenere un errore per uno specifico attributo allora possibile utilizzare getError('nomeattributo'), senza la s finale. Yii riesce a distinguere se si tratta di un nuovo inserimento o di un update in base alla propriet $model->isNewRecord. Se proviamo a creare un istanza del nostro model user e a stampare il valore di $model->isNewRecord otterremo come risultato 1. Questo vuol dire che il model pronto per inserire il nuovo record.
Dopo aver effettuato un inserimento il valore di questa propriet impotato su 0. La chiave primaria ora valorizzata con il valore che restituisce il database. Se proviamo a caricare il model, con il metodo del controller loadModel($id) o in altro modo, la propriet $model->isNewRecord restituisce 0. Il sistema quindi pronto per effettuare lupdate della riga. Dopo aver modificato il valore dei campi , e quindi delle propriet del model corrispondenti, per effettuare lupdate sufficiente richiamare il metodo save. Oltre al metodo save i sono altri metodi per aggiornare i dati nel database.
Effettua una ricerca a partire da una query sql $usr = User::model()->findBySql($sql,$parametri); Tutti i metodi restituiscono, se la trovano, una riga della tabella . Questo significa che se la query ha un riscontro nella variabile $usr, avremo unistanza dellactive record dove le varie propriet, che rappresentano i campi della tabella, sono valorizzati con i dati estratti dalla tabella. Nei metodi sopra vengono passati le variabili $sql, $condizione e $parametri.
rappresenta appunto la condizione della query. In pratica corrisponde al where di una normale query sul database. La forma pi comune : campo=:parametrocampo, in questo caso quindi
$condizione
$parametri = array(':parametrocampo'=>'valore'); $sql corrisponde ad una normale query sql in cui, sempre nel formato :nomeparametro.
Ai metodi sopra possibile passare anche unistanza della classe CDbCriteria. Come suggerisce il nome questa classe fornisce i criteri per interrogare il database. La sintassi abbastanza semplice. Mediante questa classe possibile costruire la query passo per passo.
E quindi
$usr = User::model()->find($criteria);
La classe CDbCriteria molto pi utile quando si devono realizzare query pi complesse di quella rappresentata nellesempio. Giusto per completezza di informazioni possibile passare i criteri come un unico array chiave valore. La chiavi corrispondono alle propriet della classe CDbCriteria, quindi:
$usr = User::model()->find( array( 'select'=>'nome', 'condition'=>'user=:user', 'params'=> array(":user"=>"ciro"), ) );
Come si pu verificare i metodi sono, fatta eccezione per il nome che comprende la parola All, identici a quelli descritti precedentemente. Tornando allaggiornamento dei dati, e quindi alloperazione di update , abbiamo gi visto che possibile effettuarla con il metodo save dopo aver invocato uno dei metodi per recuperare un record del database. possibile utilizzare anche i seguenti metodi per effettuare loperazione di update:
User::model()->updateAll($attributes,$conditions,$params); User::model()->updateByPk($id,$attributes,$conditions,$params);
Come si intuisce, il primo metodo consente di modificare tutte le righe di una tabella in base ad una specifica condizione e i relative parametri. $attributes un array costituito dai valori delle colonne. Il secondo metodo consente di effettuare lupdate di una singola riga in base al valore della chiave primaria $id. I metodi indicati non effettuano la validazione sui dati. Per completare linsieme dei metodi che ci consentono di effettuare le operazioni CRUD sul nostro database, non ci resta che verificare in che modo Yii cancelli i dati dal nostro database. Il metodo pi semplice quello di caricare il record in un model e, successivamente, invocare il metodo delete.
$usr = User::model()->findByPk($id); $usr->delete();
Anche in questo caso non affatto necessario recuperare il record prima di eliminarlo.
Infatti il metodo
User::model()->deleteByPk($id,$conditions,$params);
del tutto equivalente al precedente. Prima di concludere la nostra panoramica sulle operazioni CRUD ci sono ancora alcune cose di cui dobbiamo parlare. Pu capitare infatti di voler effettuare operazioni di inserimento , aggiornamento o eliminazione multipla ma che tali modifiche abbiano effetto solo se tutte le nostre query hanno successo. Stiamo parlando ovviamente di utilizzare le transazioni sul database . Yii consente di effettuare tutte le query in ununica transazione in modo semplice e veloce.
$transaction = $model->dbConnection->startTransacation(); try { //Qui vanno inserite tutte le operazioni sul database $transaction->commit(); } Catch(Exception $e) { $transaction->rollback(); }
I nomi dei metodi sono abbastanza esplicativi. Ad ogni modo il primo metodo consente di eseguire una query di conteggio (come select count(nome campo) FROM tabella $condizione) passando la condizione e i parametri necessari. Il secondo metodo consente di effettuare il conteggio passando una intera query e i relativi parametri. Infine il terzo metodo verifica lesistenza di un determinato record nel database in base alla condizione e i parametri passati. Un altro metodo molto importante relations. Il nome indica chiaramente che in questo metodo si tiene conto delle relazioni che questa tabella ha con le altre . Ovviamente se abbiamo due tabelle in relazione tra loro, questo metodo riporter, in ognuno dei model che le rappresentano, la relazione. La differenza consister nel tipo di relazione. Affinch Yii riconosca in automatico le relazioni, e quindi che il modulo gii sia in grado di creare i model con le relazioni, necessario che
nel database sia creata una relazione esterna fra campi. In caso contrario sempre possibile creare le relazioni manualmente modificando il metodo relations. I tipi di relazioni che possono esistere sono quelle tipiche dei database relazionali:
BELONGS_TO: relazione molti a uno HAS_MANY: relazione una a molti HAS_ONE: relazione uno a uno MANY_MANY: relazione molti a molti
In cui:
relazione1 indica il nome della relazione self::BELONGS_TO Il tipo di relazione model2
il model (tabella) a cui intendiamo collegarci il campo del nostro model(tabella) legato alla tabella rappresentata da
campoRelazione
model2 A questo punto per utilizzare le relazioni non ci resta che richiamare un metodo di ricerca tipo find o findAll e insieme al metodo with
$user = User::model()->with('relazione1')->findAll();
oppure
$criteria->with = array('relazione1','relazione2');
Uno degli aspetti pi interessanti del model rappresentato dalla possibilit di utilizzare gli scopes. Se vi state chiedendo cosa sia uno scope possiamo semplificare dicendo che uno scope un sistema che consente di applicare un criterio di query, o pi criteri combinati tra loro, su un active record. Esistono due modi diversi per definire uno scope allinterno del nostro model. Nel primo caso ogni scope indice di un unico array definito allinterno del metodo scopes:
public function scopes() { return array( 'admin'=>array( 'condition'=>'status=1', ), 'date'=>array( 'order'=>'date DESC', 'limit'=>5, ), ); }
Per applicare lo scope alla nostra query sufficiente un codice come il seguente:
$user = User::model()->admin->findAll();
oppure:
$user = User::model()->date->findAll();
La soluzione proposta va bene in caso di scope e filtri che non richiedono parametri passati dallutente. Infatti, se volessimo passare dei parametri al nostro scope, la sintassi da utilizzare come quella che segue:
public function dataIscrizione($date) { $this->getDbCriteria()->mergeWith(array( 'condition'=>"data_iscrizione >= '$date'" )); return $this; }
Il codice proposto nellultimo metodo abbastanza semplice. Il metodo non fa altro che prelevare i criteri che gi sono applicati al model, infatti $this nel contesto rappresenta il model, ed aggiungere quelli definiti nello scope mediante il metodo, della classe CDbcriteria, mergeWith.
Avere una rappresentazione sotto forma di classe PHP del form di cui vogliamo i dati. Avere svariate action nel nostro controller per gestire tutte le fasi di un form (verifica dei dati, invio dei dati, messaggi di errore). Avere un file di tipo vista nel quale con poche righe di codice, rappresentare il nostro form.
Come esercizio proviamo la creazione di un banale form per la raccolta dei dati anagrafici di una persona. Il nome del file, che ricordo va posizionato sempre nella cartella model, RubricaForm.php. Il nome composto dai termini Rubrica e Form, cosa che ci aiuta a capire immediatamente che parliamo del:
Il nome della classe sar uguale al nome del file. La base di partenza della nostra classe sar:
class telefono extends CFormModel{ public $nome; public $cognome; public $telefono; }
Come si vede non abbiamo fatto altro che aggiungere tre propriet alla nostra classe , che ovviamente rispecchieranno i nomi dei campi del form stesso. Gli autori di Yii specificano che non si tratta di vere propriet, ma piuttosto di attributi. Ogni attributo rappresenta una propriet in cui vengono gestite le informazioni inviate mediante il form(un attributo per ogni campo). Uno dei passaggi principali per la gestione del form la validazione dei dati inviati. Anche in questo caso il metodo che si occupa della cosa il metodo rules.
public function rules() { return array( array('nome, cognome, telefono', 'required'), array('nome, cognome, telefono', 'length','max'=>255), ); }
Nel nostro caso le regole di validazioni sono abbastanza intuitive. Ci preoccupiamo infatti solo che i campi non siano vuoti e che la loro lunghezza massima sia pari 255 caratteri. Valgono per i CFormModel gli stessi concetti espressi in merito la validazione di CActiveRecord.
A questo punto ci si chiede se ci sia a disposizione un sistema rapido e veloce affinch i nostri attributi siano valorizzati con i campi che arrivano dal form. Normalmente siamo abituati a leggere i nomi dei campi del form utilizzando la seguente sintassi:
$nome = $_POST['nomecampo'];
In Yii i nomi dei campi sono leggermente pi complessi. Facendo riferimento al nostro esempio stiamo considerando un form di tipo post ci ritroveremo un form i cui campi hanno un nome nel seguente formato:
$_POST['RubricaForm']['nome'] $_POST['RubricaForm']['cognome'] $_POST['RubricaForm']['telefono']
Fatta questa premesse il modo pi semplice per valorizzare i nostri attributi con i campi del form banalmente:
public function generic(){ $model = new RubricaForm(); if(!empty($_POST['RubricaForm'])) $model->attributes = $_POST['RubricaForm']; }
Come si vede sufficiente fare una semplice assegnazione. Questo genere di assegnazione viene definita massiva. In pratica, riferendoci allultima riga di codice, ogni attributo del nostro model viene valorizzato con il corrispettivo valore contenuto nellarray associativo $_POST['RubricaForm']. Bisogna prestare attenzione che lassegnazione massiva funziona solo con gli attributi di tipo safe. In merito si vede la sezione relativa alla validazione nel paragrafo CActiveRecord. A questo punto non ci resta che validare i dati e proseguire con le nostre operazioni:
$model->validate()
Questa riga ci consentir di verificare la gestione degli errori del form. Effettuate il login poich le operazioni CRUD sono permesse solo agli utenti registrati e puntate il vostro browser alla pagina che consente di creare un nuovo utente. Dovrebbe essere /user/create. Il file che genera quello che visualizziamo situato nella cartella /views/user/_form.
Senza preoccuparci di quello che scritto nel file, proviamo ad inviare il form senza riempire i campi. Come vedrete vi saranno mostrati a video gli errori in base alle regole definite nel model. A prescindere dallo stile, che quello fornito da Yii e che potete tranquillamente personalizzare, noterete come, con poche righe di codice, avrete un form, con tanto di gestione degli errori, in meno di 40 righe di codice. Nel file _form.php modificate la seguente riga di codice
'enableAjaxValidation'=>false,
in
'enableAjaxValidation'=>true,
infine aggiungete
array ('user, password, mail', 'length', 'min'=>8),
alle regole del nostro model. Richiamate nuovamente la pagina per linserimento di un nuovo utente e provate a scrivere ciro nella casella user. Noterete che alla pressione del tasto tab, o in ogni caso quando la casella user perde il focus, viene effettuata una validazione dei dati utilizzato una chiamata Ajax. Considerando che abbiamo apportato giusto qualche modifica direi che non male. A questo punto giunto il momento di analizzare del come tutto questo sia possibile e per farlo dobbiamo analizzare il file _form.php di cui abbiamo parlato allinizio del capitolo. Tralasciano i vari tag HTML che poco ci interessano, notiamo che, allinizio e alla fine del file, presente un widget che ci consente di creare un blocco form allinterno della nostra vista.
$form=$this->beginWidget('CActiveForm', array( 'id'=>'user-form', 'enableAjaxValidation'=>true, ));
interessante notare che si tratta di un active form, cio un widget dedicato alla creazione di form complessi in modo semplice e veloce. Guardando il codice scritto sopra appare evidente che il primo parametro indica il tipo di widget mentre il secondo, in questo caso, rappresenta una serie di parametri utili alla creazione del form. In questo specifico caso diciamo ad Yii di attribuire allattributo id del form il valore user-form e di abilitare la validazione ajax. La seguente riga di codice
echo $form->errorSummary($model);
ci consente di vedere il riepilogo degli errori. Tutti i metodi presenti nella pagina legati alloggetto form sono dei wrapper della classe ausiliare CHtml. Questa classe consente di generare gli oggetti tipici di una pagina HTML quali button, label,
campi di testo etc. Nel caso dellActiveForm questi campi, sono legati ad una propriet del model stesso. Prendiamo ad esempio le seguenti righe di codice:
<?php echo $form->labelEx($model,'user'); ?> <?php echo $form->textField($model,'user',array('size'=>60,'maxlength'=>255)); ? > <?php echo $form->error($model,'user'); ?>
Il primo metodo fornisce una label il cui valore quello definito allinterno del metodo attributeLabels del nostro model. Il metodo textField genera un campo di testo per il campo user, con le propriet indicate nel secondo parametro. Per finire error visualizza gli errori relativi al campo user a seguito della validazione.
Gestire il database
Yii consente di accedere a molti database come MySql, Postgree, MsSql e tutti quelli supportati da PDO. Infatti il Data Access Object (DAO) di Yii si basa appunto su PDO. Fondamentalmente ci sono 4 classi che compongono DAO. Queste sono:
CDbConnection: rappresenta la connessione al database CDbCommand: rappresenta una query sql CDbDataReader: rappresenta un result set CDbTranscation: rappresenta una transazione sul database
La connessione al database
Per effettuare una connessione al database sufficiente utilizzare la seguente riga di codice:
$connection=new CDbConnection($dsn,$username, $password);
La variabile $dsn varia a seconda del database a cui ci colleghiamo. Nel caso di MySql, il database pi utilizzato in accoppiata col PHP, il valore nel formato:
mysql:host=localhost;dbname=mio database
Istanziando la classe connection abbiamo a disposizione una connessione con il database. Per chiudere la connessione possibile utilizzare il comando
$connection->active=false;
La classe CdbConnection estende la classe base CApplicationComponent. Per questo motivo, allinterno del file di configurazione, trovavamo il codice che definisce la nostra connessione. Nella lista dei componenti attivi infatti, presente db. Il motivo che in questo modo in qualsiasi punto dellapplicazione sempre disponibile una connessione attiva con il database.
Per accedere alla connessione definita nel file di configurazione si pu utilizzare la seguente sintassi:
$db = Yii::<em>app</em>()>db;
Le operazioni Crud
Dopo aver visto come connetterci al database giunto il momento di vedere come effettuare le operazioni CRUD su di esso. Il primo passo quello di creare una istanza dell oggetto CDbCommand scrivendo:
$command=$connection->createCommand($sql);
Se la nostra query di tipo insert, update o delete allora sufficiente invocare il metodo execute che restituisce il numero di righe interessate dalla query:
$rowCount=$command->execute();
$rows=$command->queryAll();
La differenza dei due metodi consiste nel fatto che, nel primo caso, otterremo un dataReader come risultato mentre nel secondo un array contenente i dati. Per recuperare i dati da un dataReader si utilizza il codice che segue:
while (($row=$dataReader->read())! ==false) { [...] }
oppure
foreach ($dataReader as $row) { [...] }
Le transazioni
Prima di concludere la breve panoramica su DAO, dobbiamo chiarire in che modo Yii utilizza le transazioni. Come abbiamo detto DAO si appoggia su PDO quindi valgono gli stessi criteri. Una transazione pu essere iniziata con
$transaction=$connection->beginTransaction();
Il framework fornisce uno scheletro di una classe sulla quale basare lautenticazione. Il sistema fornito quello classico che si basa su una coppia username / password ma gli stessi autori non escludono la possibilit di utilizzare altri sistemi di autenticazione come LDAP e addirittura Facebook Connect e Twitter auth. La classe dedicata allo scopo si trova ovviamente sotto components. Il nome del file userIdentity cos come il nome della classe che estende CUserIdentity. Il codice che riporto sotto va implementato nel file userIdentity.
private $_id; public function authenticate() { $pwd = md5($_POST['LoginForm']['password']); $user = $_POST['LoginForm']['username'];
$record =User::model()>findByAttributes(array('user'=>$user,'password'=>$pwd)); if($record===null){ $this->errorCode=self::ERROR_USERNAME_INVALID; $this->errorCode=self::ERROR_PASSWORD_INVALID; }else{ $this->_id=$record->id; $this->errorCode=self::ERROR_NONE; } return !$this->errorCode; } public function getId() { return $this->_id; }
Il codice riportato sopra a puro titolo di esempio e non adatto ad essere implementato in una web application reale. Il suo scopo solo mostrarvi un minimo di codice con il quale effettuare una autenticazione sfruttando un database. Il codice abbastanza semplice. Effettuiamo la ricerca della coppia user password, opportunamente codificata in md5, sulla tabella user mediante il suo model. Per farlo utilizziamo il metodo findByAttributes che, come suggerisce il nome, permette di effettuare una ricerca in base a dei campi di una tabella. Il metodo consente anche di passare come secondo e terzo parametro una condizione, che viene applicata alla query, e dei parametri. In caso la coppia venga trovata, il metodo restituisce true e tutte le informazioni dellutente sono contenute nella classe. Vi ricordo che il controller user generato dal modulo gii, non prevede lutilizzo della funzione md5 per il campo password. Se ricordate, quando abbiamo parlato dei models, abbiamo posto evidenza sul metodo rules. Questo metodo restituiva un array associativo, nel quale erano dichiarati i filtri di accesso alle varie action del controller. Nel metodo filter era indicato come sistema di controllo :accessControl. I due metodi, o per meglio dire gli array che restituiscono, cos configurati, consentono di effettuare un controllo sulla tipologia di utente.
Component e modules
Per concludere il nostro viaggio allinterno del mondo di Yii non ci resta che parlare dei moduli e dei componenti (components). I moduli sono delle vere e proprie applicazioni integrate allinterno della nostra web application. Ogni modulo infatti dotato di viste, controller e model propri. Il vantaggio di suddividere lapplicazione in moduli evidente in applicazioni di una certa complessit nelle quali, ogni modulo, svolge una specifica funzione. Il modulo viene integrato allinterno dell'applicazione attraverso il file di configurazione:
return array( cut 'modules'=>array('mioModulo'=>array("parametroModulo"=>"valore"),
cut );
I moduli sono posizionati nella cartella modules che si trova nella root della nostra applicazione. Ogni modulo identificato in modo univoco dal nome della cartella. Per accedere ad un modulo e ai suoi controlli sufficiente anteporre alluri solito, cio nome-Controller/action, il nome del modulo stesso: nome-Modulo/nome-Controller/action. I componenti sono classi particolari di Yii che estendono una classe base del framework che CComponent. Il vantaggio di creare un componente invece di una semplice classe, dovuto al fatto che in questo modo possibile sfruttare le caratteristiche tipiche del componente. I component sono situati allinterno della cartella component sotto la root della nostra applicazione. Le caratteristiche principali di un component sono le Property, Event e per finire i Behavior. Le property, o se preferite in italiano le propriet, non sono altro che delle variabili pubbliche della classe dotate di un metodo set e di un metodo get. Gli eventi (events) sono delle propriet il cui valore quello restituito da una funzione di ritorno definita come called event handler. Per finire i behavior (in italiano comportamenti), sono degli oggetti che possono essere attaccati, e quindi usati, dai components. Questo genere di classi derivano dalla classe basi CBehavior ma, in caso volessimo attaccare i behavior ad un model potremmo estenderli dalla classe
CAtiveRecordBehavior
Da notare, facendo riferimento al file di configurazione, che tutti i componenti presenti nella cartella principale dei components sono importati di default.
Conclusioni
Yii dispone di un ottimo sistema per la gestione degli errori. Senza scendere troppo nel dettaglio vi basti sapere che configurando opportunamente il file di configurazione, c la possibilit di effettuare il log degli eventi su file, database e addirittura a mezzo mail. Mediante poche righe di codice possibile addirittura dire al framework, di inserire nei log le query che vengono effettuate sul database con i valori dei parametri passati. I widget sono degli oggetti che svolgono per noi determinate funzioni. Con un widget possibile inserire form, datepicker, gridview e molti altri oggetti con poche righe di codice. Grosso modo hanno la stessa funzionalit delle classi helper ovvero quelle classi che ci facilitano la scrittura del codice. Una su tutte la classe CHtml e il metodo ajax. Come intuirete dal nome questo metodo ci consente di effettuare una chiamata ajax, invocando un metodo PHP e passando i pochi parametri necessari per la configurazione. Penser Yii ad inserire tutto il codice necessario affinch il tutto avvenga. Per finire ci sono le estensioni cio piccole applicazioni scritte da terze persone che possono essere implementate nella nostra, per ampliare le funzionalit offerte da Yii.
Conclusioni
Quello che mi ha sempre tenuto lontano dallutilizzare un framework per sviluppare le mie applicazioni, la complessit che molti di essi mostravano. Yii Framework invece si presenta come
un framework che in pochi click ci rende operativi. Abbiamo visto infatti nel corso di questa breve guida, di come sia possibile creare con pochi passaggi, le pagine necessarie alla gestione delle tabelle del nostro database. A rendere Yii un framework cui prestare attenzione, anche lottima integrazione del pattern MVC. I model consentono di effettuare tutte le operazioni di base sulle tabelle senza nemmeno scrivere una riga di codice. Grazie allausilio del modulo gii i model e tutti i file necessari per le operazioni CRUD, vengono autogenerati. Yii consente di interagire con i pi diffusi database ma fornisce allutente sempre la stessa interfaccia per svolgere le operazioni di manipolazione dei dati. A completare il quadro c unottima gestione degli url, una serie di classi di aiuto, widgets, componenti ed estensioni. Per finire va ricordata lottima documentazione offerta dal sito ufficiale e lottimo supporto presente sul forum. La guida solo in lingua inglese e anche per il forum, nonostante la presenza della versione italiana, consigliabile lutilizzo in lingua inglese poich accoglie un bacino di utenti pi numeroso.