Files
yii/docs/guide/it/basics.controller.txt
2012-01-01 03:05:53 +00:00

340 lines
12 KiB
Plaintext

Controller
==========
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`:
~~~
[php]
class SiteController extends CController
{
public function actionIndex()
{
// ...
}
public function actionContact()
{
// ...
}
}
~~~
Route
-----
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|CWebApplication::controllerMap]
>che la [mappa delle action|CController::actions] abbiano le chiavi in minuscolo.
Un'applicazione può contenere [moduli](/doc/guide/basics.module). 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](/doc/guide/basics.module).
Instaziazione del Controller
------------------------
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](/doc/guide/basics.module), 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.
Action
------
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:
~~~
[php]
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()|CController::actions] della nostra classe controller:
~~~
[php]
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
~~~
### Associazione dei parametri all'Action
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`:
~~~
[php]
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:
~~~
[php]
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:
~~~
[php]
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,
~~~
[php]
class UpdateAction extends CAction
{
public function run($id)
{
// $id sarà impostato con il valore di $_GET['id']
}
}
~~~
Filter
------
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:
~~~
[php]
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:
~~~
[php]
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,
~~~
[php]
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.
<div class="revision">$Id: basics.controller.txt 3251 2011-06-01 00:24:06Z qiang.xue $</div>