Sei sulla pagina 1di 34

Guida Yii Framework php

Introduzione
1. Vantaggi, requisiti e installazione

La prima applicazione
2. Creare una web application
3. Struttura dell'applicazione Yii
4. Yii in azione: il file index.php
5. I file di configurazione
6. Url seo friendly
7. 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. Creare un form: la classe CFormModel
15. Creare un form: raccogliere i dati
16. Gestire il database
17. Autenticazione degli utenti
18. Component e modules
19. Conclusioni
Vantaggi, requisiti e installazione
Yii occupa un posto di rilievo nello scenario sempre più vasto dei framework PHP. Basato sui
componenti ed estensioni, Yii viene definito dagli autori come un framework scritto per consentire
lo sviluppo di applicazioni web in modo facile ma soprattutto veloce. Il nome particolare è un
acronimo delle parole “Yes, it is” e rappresenta la risposta alle mille domande che uno sviluppatore
si pone rispetto ad un framework: è veloce? È Sicuro? È adatto al nostro scopo? In questa guida
risponderemo a queste domande e vi illustreremo le basi per poter iniziare a lavorare con il
framework.

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 all’esterno 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 l’update del framework su un server di prova e verificare che
tutto funzioni perfettamente.

Tornando all’installazione 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

 Demos
 Framework
 Requirements
 Changelog
 License
 Readme
 Upgrade

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 all’utilizzo di Yii. Ci sono esclusivamente
dei warning che indicano che per determinate funzionalità devo abilitare alcune estensioni di PHP.
Possiamo ignorarle e passare avanti.
Creare una web application
A questo punto non resta altro da fare che lanciare lo script che crea la nostra prima web
application con Yii. Aprite il vostro terminale, o in caso usiate Windows, il prompt dei comandi,
posizionatevi nella cartella Framework che si trova, ovviamente, nella cartella in cui avete
posizionato Yii e lanciare il seguente comando:

#Se si utilizza Windows


yiic.bat webapp path_yii/app

#Se si utilizza Linux


yiic webapp path_yii/app

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:

 Protected/controllers
 Protected/models
 Protected/views
 Protected/runtime

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 l’aggiornamento può essere realizzato semplicemente
facendo un update della nostra copia locale.
È opportuno, come abbiamo indicato già in precedenza, prima di eseguire un’azione del genere sul
server di produzione, di effettuare un test su un server di prova di tutte le applicazioni interessate
dall’update.

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 l’aspetto della home-page.

Struttura dell’applicazione Yii


Prima di proseguire nella guida è bene soffermarci un momento sulla struttura del file system della
nostra applicazione. Abbiamo organizzato nella seguente tabella le informazioni dettagliate su come
il framework organizza i file e le directory di una webapp. Per ogni cartella e file è presente una
breve descrizione della sua funzione che vi aiuterà nel capire a cosa serve quella specifica cartella o
specifico file.

applicazione

index.php //il file di ingresso per l’applicazione

index-test.php //il file di ingresso per i test sull’applicazione

assets/ //contiene file pubblicati in precedenza

css/ //contiene i fogli di stile

images/ //contiene le nostre immagini

themes/ //contiene i temi dell’applicazione


protected/ //contiene i file protetti dell’applicazione

yiic //yiic command line script per utenti Linux

yiic.bat //yiic command line script per utenti Windows

yiic.php //yiic command line PHP script

commands/ //comandi personalizzati per le applicazioni consolle

shell/ //contiene i comandi shell per le applicazioni consolle

components/ //contiene i componenti

Controller.php //la classe base del controller

UserIdentity.php //classe usata per l’autenticazione

config/ //contiene i file di configurazione

console.php //file di configurazione per le applicazioni consolle

main.php //file di configurazione per le applicazioni web

test.php //file di configurazione per le unità di test

controllers/ //contiene le classi controller

SiteController.php //il controller di default dell’applicazione

data/ //dati di esempio del database

schema.mysql.sql //the DB schema di MySql

schema.sqlite.sql //the DB schema di SqlLite

testdrive.db //dati esempio di SqlLite

extensions/ //contiene le estensioni di terze parti

messages/ //contiene la traduzione del testo nelle varie lingue

models/ //contiene le classi di tipo model

LoginForm.php //model login

ContactForm.php //model contatti

runtime/ //file temporanei generati in fase di esecuzione

tests/ //contiene i file di test

views/ //contiene le viste e il layout dell’applicazione

layouts/ //contiene il layout

main.php //il layout condiviso da tutte le pagine

column1.php //layout a singola colonna

column2.php //layout a doppia colonna

site/ //vista per il controllo site


pages/ //contiene pagine statiche

about.php //vista della pagina about

contact.php //la vista della pagina contatti

error.php //la vista degli errori

index.php //la vista della pagina index

login.php //la vista per l’action login

Ricordo che queste cartelle sono situate all’interno 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 un’applicazione 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 l’applicazione
 Ext: la cartella extensions

Yii in azione: il file index.php


Analizzando il file di ingresso della nostra applicazioni, il file index.php, si può notare da subito che
l’applicazione viene avviata mediante il richiamo di un metodo statico della classe Yii

Yii::createWebApplication($config)->run();

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.

Scrivendo infatti una cosa del tipo

echo Yii::getPathOfAlias('webroot');

verrà visualizzato il percorso della nostra applicazione.

Conoscere questi percorsi è molto utile quando bisogna importare i file all’interno 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 l’ausilio 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 all’interno di quelle
definite dall’alias, vengono concatenate all’alias mediante il punto. Quindi utilizzando l’alias
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.

Chiave Funzione
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 l’array 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 dell’array 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.

Url seo friendly


Grazie al modulo urlManager, inserendo poche righe di codice nel file .htaccess è possibile avere
url del tipo www.miohost.com/controller/action. Le righe di cui parliamo non fanno altro che dire al
server di eliminare index.php dall’url (grosso modo). Le righe sono:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php
RewriteRule . index.php

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')),

aggiungendo quindi “../”, senza virgolette, agli uri.

Modulo Gii
Prima di entrare nel dettaglio dell’utilità 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
l’operazione.

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 l’accesso 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 Model-
View-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 l’url
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, l’uri 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 all’uri precedente “/nomeAzione” ovviamente senza il prefisso action e senza
virgolette. Qualora all’uri non venga passata nessuna azione, il controller esegue l’azione
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 l’identificativo di
tali elementi. Per cui potremmo dire che per richiamare un'azione di un controller basta aggiungere
all’uri di base IDController/IDAzione.

Qualora Yii non riesca ad individuare un controller, o un'azione, con l’id passato nella uri, verrà
mostrato a video il classico errore 404.

Lo scopo ultimo del controller è quello di rendere una vista all’utente 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 l’url 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 dell’action 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 l’insieme della azioni personalizzate.

L’array è di tipo associativo e in esso la chiave rappresenta l’identificativo dell’azione, nel nostro
caso login, mentre il valore della chiave indica il path al file che contiene la definizione dell’azione
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
run.

La forma della classe è :


class login extends CAction

public function run()

echo "Ciao mondo";

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 :

 controllo: è il primo valore e può essere allow or deny


 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 *: tutti gli utenti
o admin: l’utente admin
o @: utenti autenticati

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 l’output all’utente 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 all’id 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 l’albero 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.

L’operazione di renderizzazione di una vista avviene all’interno 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 l’estensione 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 all’interno 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 dell’array parametri. È facile intuire che in questo modo possiamo visualizzare nella
vista tutti i dati che vogliamo.

Richiamare il metodo render vuol dire mostrare, all’interno 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 all’inizio
e alla fine di ognuno troviamo il seguente codice:

<?php $this->beginContent('//layouts/main'); ?>

<?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 l’istanza del controller che invoca la vista.

Bisogna assolutamente che ricordiate questa cosa. Infatti all’interno delle viste potranno essere
renderizzati dei widget, di cui discuteremo più avanti, mediante l’istanza 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 l’url.

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 l’uri 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 l’utente è un guest
o un utente registrato. Sfruttando questa proprietà, insieme all’attributo 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 all’interno della vista. In
poche parole se ci sono javascript all’interno del codice questi vengono processati.

Introduzione a CActiveRecord
Come sappiamo uno degli aspetti principali di una web application è l’utilizzo di una base di dati.
Yii ci consente di interagire con differenti tipi di database: MySql, MsSql, Oracle ecc.. L’utilizzo di
una base di dati invece che un’altra, avviene in modo del tutto trasparente per l’utente. 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,
all’interno del file di configurazione, una connessione al database. Infatti, anche se avviene in modo
del tutto trasparente all’utente, 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 l’override 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 dell’underscore. Se lato database la cosa è funzionale lo
è molto meno quando si tratta di presentare il contenuto all’utente. Questo metodo ci consente,
mediante un array di tipo associativo, di collegare ad ogni campo della tabella una etichetta.

Uno dei metodi più importanti all’interno 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 l’utente e il sistema. Uno
scenario può essere pensato appunto come una serie di azioni che portano ad un determinato stato
del sistema. Si immagini l’operazione 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 all’utente

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 l’obbligatorietà dei campi, dall’interno 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.

Le operazioni CRUD: update ed insert


È 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 all’interno 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 l’equivalente 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 l’id semplicemente leggendo il valore della
proprietà dell’id. 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 all’interno 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 l’inserimento è andato a buon fine. Qualora qualcosa vada storto, è probabile
che uno dei campi non sia validato. L’insieme degli errori degli attributi è inserito all’interno 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 l’update della riga. Dopo aver modificato il
valore dei campi , e quindi delle proprietà del model corrispondenti, per effettuare l’update è
sufficiente richiamare il metodo save. Oltre al metodo save i sono altri metodi per aggiornare i dati
nel database.

Le operazioni CRUD: select e delete


La nostra classe eredita dalla classe padre il metodo statico model. Questo metodo restituisce una
istanza di active record che ci consente di accedere ai metodi della classe stessa. Detto questo
diciamo che sfruttando questo metodo, esistono diversi sistemi per poter recuperare una riga della
nostra tabella.

Ricerca una riga nella tabella in base a delle condizioni

$usr = User::model()->findByPk($id,$condizione, $parametri);

Effettua la ricerca in base alla chiave primaria e altre condizioni

$usr = User::model()->findByAttributes($attribute,$condizione, $parametri);

Effettua una ricerca su uno specifico campo e su una determinata condizione


$usr = User::model()->findBySql($sql,$parametri);

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 un’istanza dell’active 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.

 $condizione 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

$parametri = array(':parametrocampo'=>'valore');

 $sql corrisponde ad una normale query sql in cui, magari, sono definiti dei parametri
sempre nel formato :nomeparametro.

Ai metodi sopra è possibile passare anche un’istanza 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.

$criteria = new CDbCriteria();


$criteria->select = "nome";
$criteria->condition = "user=:user";
$criteria->params = array(":user"=>"ciro");

E quindi

$usr = User::model()->find($criteria);

La classe CDbCriteria è molto più utile quando si devono realizzare query più complesse di quella
rappresentata nell’esempio.

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"),
)
);

Per individuare più record ci vengono in soccorso i seguenti metodi.

$usr = User::model()->findAll($condition,$params);
$usr = User::model()->findAllByPk($id,$condition,$params);
$usr = User::model()->findAllByAttributes($attributes,$condition,$params);
$usr = User::model()->findAllBySql($sql,$params);
Come si può verificare i metodi sono, fatta eccezione per il nome che comprende la parola All,
identici a quelli descritti precedentemente.

Tornando all’aggiornamento dei dati, e quindi all’operazione 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 l’operazione 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 l’update di una singola riga in base al valore della
chiave primaria $id. I metodi indicati non effettuano la validazione sui dati.

Per completare l’insieme 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 un’unica 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();
}
Metodi utili, scope e relazioni
Uno dei metodi che la nostra classe User eredita da CActiveRecord, ma che non è visibile nel
nostro file , è primaryKey. L’utilità di questo metodo è ovvia: restituisce la chiave primaria della
tabella. Nel caso che la tabella abbia come chiave un gruppo di campi, questi saranno restituiti
sottoforma di array e non di singolo elemento. In pratica invece di return 'chiave'; avremo
return array('k1','k2');.

Altre funzioni utili sono:

User::model()->Count($conditions,$params);
User::model()->countBySql($sql,$params);
User::model()->exists($condition,$params);

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 l’esistenza
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

Un esempio del metodo relations è il seguente:

public function relations()


{
return array(
'relazione1'=>array(self::BELONGS_TO,'model2','campoRelazione')
);
}

In cui:

 relazione1 indica il nome della relazione


 self::BELONGS_TO Il tipo di relazione
 model2 il model (tabella) a cui intendiamo collegarci
 campoRelazione il campo del nostro model(tabella) legato alla tabella rappresentata da
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();

Per ottenere un campo della tabella collegata è sufficiente scrivere

$user->relazione1->nome_campo

Se vogliamo effettuare la join su più tabelle possiamo scrivere

$user = User::model()->with('relazione1','relazione2')->findAll();

È possibile sfruttare le relazioni delle tabelle anche usando i criteri.

$criteria = new CDbCriteria();


$criteria->with = "relazione1";
$user = User::model()->findAll($criteria);

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 all’interno del nostro model. Nel primo
caso ogni scope è indice di un unico array definito all’interno 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();

e per finire la combinazione dei due:

$user = User::model()->admin->date->findAll();
La soluzione proposta va bene in caso di scope e filtri che non richiedono parametri passati
dall’utente. 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;
}

Quindi il codice precedente può essere scritto nel modo seguente:

$oggi = date("Y-m-d");
$user = User::model()->admin->dataIscrizione($oggi)->findAll();

Il codice proposto nell’ultimo 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.

Creare un form: la classe CFormModel


Come già avevo anticipato poco prima nel corso di questa guida, il concetto di Model in Yii si
suddivide in CActiveRecord, del quale abbiamo già parlato nella lezione precedente, e di
CFormModel, che in Yii è un modo semplice e veloce di rappresentare e manipolare i form. Grazie a
questa classe è possibile realizzare in modo semplice e veloce form perfettamente funzionanti.
Grazie ad un model di tipo form saremo in grado di

 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:

 model rubrica;
 che è un model di tipo CFormModel;

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 all’ultima riga di codice, ogni attributo del nostro model
viene valorizzato con il corrispettivo valore contenuto nell’array associativo
$_POST['RubricaForm']. Bisogna prestare attenzione che l’assegnazione 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()
Creare un form: raccogliere i dati
Dopo aver visto come sia possibile manipolare i dati e come mostrarli a video, è giunto il momento
di vedere come possiamo raccoglierli. Yii mette a disposizione, tra le tante classi di helper, una
classe che ci consente di creare in pochi semplici passi un form perfettamente funzionante. In questa
fase faremo riferimento ai file che abbiamo generato all’inizio con il modulo Yii.

Verifichiamo innanzitutto che nelle regole del nostro model i campi user, password e mail siano di
tipo obbligatorio. Dovremmo trovare una riga di questo tipo:

array ('user, password, mail', 'required'),

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,

nel file userController.php individuate e decommentate la seguente riga di codice

$this->performAjaxValidation($model);

infine aggiungete

array ('user, password, mail', 'length', 'min'=>8),

alle regole del nostro model.

Richiamate nuovamente la pagina per l’inserimento 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 all’inizio del capitolo. Tralasciano i
vari tag HTML che poco ci interessano, notiamo che, all’inizio e alla fine del file, è presente un
widget che ci consente di creare un blocco form all’interno 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
all’attributo 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 all’oggetto 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 dell’ActiveForm 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 all’interno 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,


all’interno 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
dell’applicazione è 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();

Se passiamo una query di selezione allora utilizziamo i seguenti metodi:

$dataReader=$command->query();

$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)

[...]

E per finire usiamo

$rows=$dataReader->readAll();

per includere tutto il contenuto del dataReader in un array.

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();

per effettuare il commit:

$transaction->commit();

mentre per il rollBack:

$transaction->rollBack

Autenticazione degli utenti


Non poteva mancare, in un framework completo come Yii, un sistema integrato per
l’autenticazione e l’autorizzazione degli utenti. La gestione degli utenti viene effettuata mediante
il componente user, che ovviamente è precaricato. Mediante l’ausilio di questo componente
possiamo quindi effettuare le operazioni di login, logout e per finire il controllo degli accessi.

Mediante questo componente possiamo accedere alle informazioni dell’utente corrente in ogni
punto dell’applicazione mediante la seguente sintassi:
Yii::app()->user;

Il framework fornisce uno scheletro di una classe sulla quale basare l’autenticazione. 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 dell’utente sono contenute nella classe.

Vi ricordo che il controller user generato dal modulo gii, non prevede l’utilizzo 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 all’interno del mondo di Yii non ci resta che parlare dei moduli e
dei componenti (components).

I moduli sono delle vere e proprie applicazioni integrate all’interno della nostra web application.
Ogni modulo infatti è dotato di viste, controller e model propri. Il vantaggio di suddividere
l’applicazione in moduli è evidente in applicazioni di una certa complessità nelle quali, ogni
modulo, svolge una specifica funzione. Il modulo viene integrato all’interno 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 all’uri 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 all’interno 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 dall’utilizzare 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 l’ottima integrazione del pattern
MVC. I model consentono di effettuare tutte le operazioni di base sulle tabelle senza nemmeno
scrivere una riga di codice. Grazie all’ausilio 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 all’utente sempre la stessa
interfaccia per svolgere le operazioni di manipolazione dei dati. A completare il quadro c’è
un’ottima gestione degli url, una serie di classi di aiuto, widgets, componenti ed estensioni.

Per finire va ricordata l’ottima documentazione offerta dal sito ufficiale e l’ottimo supporto presente
sul forum. La guida è solo in lingua inglese e anche per il forum, nonostante la presenza della
versione italiana, è consigliabile l’utilizzo in lingua inglese poiché accoglie un bacino di utenti più
numeroso.