Il controller
è un'istanza di CController o di una classe che estende CController.
È creata dall'oggetto applicazione quando l'utente lo richiede. Quando un controller
è in esecuzione, esegue l'azione richiesta, che usualmente porta al model necessario
e visualizza la view appropriata. Un'action
, nella sua forma più elementare, è
semplicemente un metodo di una classe controller che ha il nome che inizia con action
.
Un controller ha un'action di default. Quando la richiesta dell'utente non specifica
quale action eseguire, verrà eseguita l'action di default. Per default, l'action di
default è chiamata index
. Può essere modificata impostando la variabile pubblica
CController::defaultAction dell'istanza.
Il codice che segue definisce il controller site
, l'action index
(l'action di
default) e l'action contact
:
class SiteController extends CController
{
public function actionIndex()
{
// ...
}
public function actionContact()
{
// ...
}
}
Controller ed action sono identificate da un ID.
L'ID del controller è nel formato percorso/per/xyz
, che corrisponde al file
della classe controller protected/controllers/percorso/per/XyzController.php
,
dove il segnaposto xyz
dovrebbe essere sostituito con un nome reale;
es. post
corrisponde a protected/controllers/PostController.php
.
L'ID dell'action è il nome del metodo action senza il prefisso action
. Per
esempio, se una classe controller contiene un metodo che si chiama actionEdit
,
l'ID corrispondente a questa action sarebbe edit
.
Gli utenti accedono ad un particolare controller ed action tramite route (percorso).
Una route è formata concatenando l'ID del controller con l'ID dell'action
separandoli con uno slash. Per esempio, la route post/edit
si riferisce al
controller PostController
ed all'action edit
. Di default, l'URL
http://hostname/index.php?r=post/edit
richiederà il controller post
e l'action
edit
.
Note: |Nota: Di default, le route differenziano tra maiuscolo e minuscolo (case-sensitive). È possibile rendere le route indifferenti al maiuscolo/minuscolo impostando CUrlManager::caseSensitive a false nel file di configurazione dell'applicazione. Quando si è in modalità indifferente al maiuscolo/minuscolo, assicurarsi di seguire la convenzione che le carelle che contengono i file delle classi controller siano in minuscolo, e che sia la mappa dei controller che la mappa delle action abbiano le chiavi in minuscolo.
Un'applicazione può contenere moduli. La route per
l'action di un controller all'interno di un modulo è nel formato moduleID/controllerID/actionID
.
Per ulteriori dettagli, vedere la sezione sui moduli.
Un'istanza del controller è creata quando CWebApplication gestisce una richiesta in arrivo. Dato l'ID del controller l'applicazione utilizzerà le seguenti regole per stabilire quale sia la classe controller e dove si trovi il file della classe.
Se CWebApplication::catchAllRequest è specificato, sarà creato un controller basato su questa proprietà, ed l'ID del controller specificato dall'utente sarà ignorato. Ciò è utilizzato principalmente per mettere l'applicazione in modalità manutenzione e visualizzare una pagina statica con un avviso.
Se l'ID è trovato in CWebApplication::controllerMap, la configurazione del corrispondente controller verrà utilizzata per creare l'istanza di quel controller.
Se l'ID è nel formato 'percorso/per/xyz'
, il nome della classe del controller
si assume essere XyzController
e il corrispondete file della classe sarà
protected/controllers/percors/per/XyzController.php
. Per esempio, il controller ID
admin/user
sarà mappato con la classe controller UserController
ed il file
della classe sarà protected/controllers/admin/UserController.php
.
Se il file della classe non esiste, sarà generato un errore 404 CHttpException.
Quando sono usati i moduli, la procedura descritta sopra è leggermente diversa. In particolare, l'applicazione controllerà se l'ID si riferisce o meno ad un controller contenuto in un modulo, ed in tal caso, sarà prima creata una istanza del modulo, seguita dall'istanza del controller.
Come notato in precedenza, un'action può essere definita come un metodo il cui
nome inizia con la parola action
. Una tecnica più avanzata è quella di definire
una classe action e chiedere al controller di istanziarla quando richiesto. Ciò
consente alle action di poter essere riutilizzate e quindi si ha maggiore riusabilità.
Per definire una nuova classe action, procedere come segue:
class UpdateAction extends CAction
{
public function run()
{
// inserire qui la logica dell'action
}
}
Per far prendere coscienza al controller dell'esistenza di questa action, occorre sovraccaricare il metodo actions() della nostra classe controller:
class PostController extends CController
{
public function actions()
{
return array(
'edit'=>'application.controllers.post.UpdateAction',
);
}
}
Nel codice sopra, è stato utilizzato un path alias
application.controllers.post.UpdateAction
per specificare che il file della
classe action è protected/controllers/post/UpdateAction.php
.
Scrivendo action basate su classi, si può organizzare un'applicazione come un sistema modulare. Per esempio, la seguente struttura di cartelle può essere utilizzata per organizzare il codice dei controller:
protected/ controllers/ PostController.php UserController.php post/ CreateAction.php ReadAction.php UpdateAction.php user/ CreateAction.php ListAction.php ProfileAction.php UpdateAction.php
Sin dalla versione 1.1.4, Yii ha aggiunto il supporto per l'associazione
automatica dei parametri all'action. Vale a dire, il metodo action del controller
può definire parametri nominali il cui valore sarà automaticamente impostato da Yii
prelevandolo da $_GET
Per far vedere come questo funzioni, supponiamo di dover scrivere l'action create
per il PostController
. L'action necessita di due parametri:
category
: un intero che indica l'ID della categoria all'interno della quale il nuovo post sarà creato;language
: una stringa che indica il codice della lingua in cui il nuovo post si troverà.Potremmo concludere con il seguente codice noioso allo scopo di recuperare i valori dei parametri necessari da $_GET
:
class PostController extends CController
{
public function actionCreate()
{
if(isset($_GET['category']))
$category=(int)$_GET['category'];
else
throw new CHttpException(404,'invalid request');
if(isset($_GET['language']))
$language=$_GET['language'];
else
$language='en';
// ... il codice divertente inizia qui ...
}
}
Adesso, utilizzando la funzionalità di associazione dei parametri all'action, si può completare il compito più piacevolmente:
class PostController extends CController
{
public function actionCreate($category, $language='en')
{
$category=(int)$category;
// ... il codice divertente inizia qui ...
}
}
Notare che si aggiungono due parametri al metodo action actionCreate
.
I nomi di questi parametri devono essere esattamente gli stessi di quelli che ci
si aspetta da $_GET
. Il parametro $language
prende di default il valore en
nel caso in cui la richiesta non includa tale parametro. Poiché $category
non
ha un valore di default, se la richiesta non include il parametro category
,
sarà generata automaticamente un'eccezione CHttpException (error code 400).
A partire dalla versione 1.1.5, Yii supporta anche il tipo di dato array quale parametro dell'action. Ciò è ottenuto tramite il suggerimento di tipo del PHP utilizzano la sintassi seguente:
class PostController extends CController
{
public function actionCreate(array $categories)
{
// Yii si assicurerà che $categories sia un array
}
}
Cioè, si aggiunge la keyword array
prima di $categories
nella dichiarazione
del parametro del metodo. Così facendo, se $_GET['categories']
è una semplice stringa,
sarà convertita in un array composto solamente da quella stringa.
Nota: Se un parametro è dichiarato senza il suggerimento di tipo, significa che il parametro deve essere uno scalare (p.e., non è un array). In questo caso, passando come parametro un array tramite
$_GET
causerà un'eccezione HTTP.
A partire dalla versione 1.1.7, l'associazione automatica dei parametri funziona
anche per le action basate su classi. Quando è stato definito il metodo run()
con parametri
di una classe action, questi saranno impostati con i corrispondenti valori dei
parametri richiesti. Per esempio,
class UpdateAction extends CAction
{
public function run($id)
{
// $id sarà impostato con il valore di $_GET['id']
}
}
Il Filter è un pezzo di codice che è configurato per essere eseguito prima e/o dopo l'esecuzione dell'action di un controller. Per esempio, il filter del controllo degli accessi potrebbe essere eseguito per assicurarsi che l'utente sia autenticato prima che venga eseguita l'action richiesta; un filter per prestazioni potrebbe essere utilizzato per misurare il tempo utilizzato per eseguire l'action.
Un'action potrebbe avere molti filter. I filter sono eseguiti nell'ordine con cui appaiono nella lista dei filter. Un filter può impedire l'esecuzione di un'action nonché il resto dei filter non eseguiti.
Un filter può essere definito come un metodo della classe controller. Il nome del metodo deve
iniziare con filter
. Ad esempio, un metodo chiamato filterAccessControl
definisce
un filter chiamato accessControl
. Il metodo filter deve avere la corretta firma:
public function filterAccessControl($filterChain)
{
// chiamare $filterChain->run() per continuare l'esecuzione del filter e dell'action
}
dove $filterChain
è un'istanza di CFilterChain che rappresenta la lista dei
filter associata con l'action richiesta. All'interno di un metodo filter, si può
chiamare $filterChain->run()
per continuare l'esecuzione del filter e dell'action.
Un filter può essere anche un'istanza di CFilter o una sua classe figlio. Il codice che segue definisce una nuova classe filter:
class PerformanceFilter extends CFilter
{
protected function preFilter($filterChain)
{
// logica applicata prima che l'action venga eseguita
return true; // false se l'action non deve essere eseguita
}
protected function postFilter($filterChain)
{
// logica applicata dopo che l'action è stata eseguita
}
}
Per applicare i filter alle action, è necessario sovraccaricare il metodo
CController::filters()
. Il metodo dovrebbe restituire un array delle configurazioni
dei filter. Per esempio,
class PostController extends CController
{
......
public function filters()
{
return array(
'postOnly + edit, create',
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
Il codice precedente specifica due filter: postOnly
e PerformanceFilter
.
Il filter postOnly
è basato sul metodo (il metodo filter corrispondente è già
definito in CController); mentre il filter PerformanceFilter
è basato sugli
oggetti. Il path alias application.filters.PerformanceFilter
specifica che il file della classe filter è protected/filters/PerformanceFilter
.
Si utilizza un array per configurare PerformanceFilter
cosicché può essere
utilizzato per inizializzare i valori delle proprietà dell'oggetto filter.
Qui la proprietà unit
di PerformanceFilter
sarà inizializzata come 'second'
.
Utilizzando gli operatori più e meno, si può specificare a quale action il filter
dovrebbe o non dovrebbe essere applicato. Nel codice precedente, il filter postOnly
verrà applicato alle action edit
e create
, mentre il filter PerformanceFilter
verrà applicato a tutte le action AD ECCEZIONE DI edit
e create
. Se non appare alcun
più o meno nella configurazione del filter, il filter sarà applicato a tutte le action.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.