Files
yii/docs/guide/sv/basics.controller.txt
2011-01-16 14:55:27 +00:00

314 lines
11 KiB
Plaintext

Controller
==========
En `controller` är en instans av [CController] eller en nedärvd klass. Den
skapas av Application till följd av en request från användare. När en kontroller
körs utför den den begärda åtgärden (action), vilken vanligen laddar in
erforderliga modeller (model) samt renderar en relevant vy (view). En åtgärd är,
i sin enklaste form, en vanlig metod i kontrollerklassen vars namn börjar med
`action`
En kontroller har en standardåtgärd. Denna körs om en request från användare
inte specificerar vilken åtgärd som skall köras. Som standard har
standardåtgärden namnet `index`. Detta kan ändras genom inställningen
[CController::defaultAction].
Följande kod definierar en `site`-controller, en `index`-åtgärd (standardåtgärden),
samt en `contact`-åtgärd:
~~~
[php]
class SiteController extends CController
{
public function actionIndex()
{
// ...
}
public function actionContact()
{
// ...
}
}
~~~
Route
-----
Kontroller och åtgärd identifieras genom ID:n. Controller-ID har formatet
`path/to/xyz` motsvarande kontrollerklassfilen
`protected/controllers/path/to/XyzController.php`, där ledet `xyz` skall
ersättas med aktuella namn (t.ex. `post` motsvarar
`protected/controllers/PostController.php`). Action-ID är en åtgärds metodnamn
minus dess `action`-prefix. Exempelvis, om en kontrollerklass innehåller en
metod `actionEdit` så är ID för motsvarande åtgärd `edit`.
> Note|Märk: Före version 1.0.3, var formatet för controller-ID `path.to.xyz`
i stället för `path/to/xyz`.
Användare begär körning av en viss kontroller och åtgärd genom att ange en
route. En route består av controller-ID samt action-ID separerat av ett
snedstreck. Exempel: `post/edit` refererar till `PostController` och
dess `edit`-åtgärd. Som standard refererar URL:en
`http://hostname/index.php?r=post/edit` till denna kontroller resp. åtgärd.
> Note|Märk: Som standard är route skiftlägesberoende. Fr o m version 1.0.1, kan route
göras okänslig för skiftläge genom att inställningen
[CUrlManager::caseSensitive] sätts till false i applikationens konfiguration. I
detta läge, se till att följa konventionen att kataloger som innehåller
kontrollerklassfiler anges med gemener samt att både [controller
map|CWebApplication::controllerMap] och [action map|CController::actions]
använder gemener i sina nyckelvärden.
Fr o m version 1.0.3 kan en applikation innehålla [moduler](/doc/guide/basics.module).
En kontrolleråtgärd inuti en modul har en route på följande format
`moduleID/controllerID/actionID`. För fler detaljer hänvisas till
[avsnittet om moduler](/doc/guide/basics.module).
Instansiering av Controller
---------------------------
En kontrollerinstans skapas när [CWebApplication] behandlar en inkommande
request. Givet ett kontroller-ID använder sig Application av följande regler för
att bestämma kontrollerklass samt var dess klassfil är placerad.
- Om [CWebApplication::catchAllRequest] har specificerats, skapas en kontroller baserat på denna property och användarspecificerat kontroller-ID ignoreras. Detta används i första hand till att sätta applikationen i underhållsläge och visa en informationssida.
- Om begärt ID kan hittas i [CWebApplication::controllerMap], används motsvarande kontrollerkonfiguration för att skapa kontrollerinstansen.
- Om begärt ID har formatet `'path/to/xyz'`, förmodas kontrollerklassen vara `XyzController` och motsvarande klassfil `protected/controllers/path/to/XyzController.php`. Exempelvis kontroller-ID `admin/user` löses upp som kontrollerklassen `UserController` med klassfilen `protected/controllers/admin/UserController.php`. Om klassfilen inte kan hittas ges en 404 [CHttpException].
Om [moduler](/doc/guide/basics.module) används (tillgängligt fr o m version 1.0.3),
är ovanstående process aningen annorlunda. Mer detaljerat, applikationen kontrollerar
om ID:t refererar till en kontroller inuti en modul och om så är fallet skapas
modulinstansen först, därefter kontrollerinstansen.
Action
------
Som tidigare nämnts kan en åtgärd definieras som en metod vars namn börjar med
`action`. Ett mer avancerat sätt att definiera en åtgärd är att definiera en
åtgärdsklass och be kontrollern instansiera denna på begäran. Detta ger bättre
återanvändningsbarhet då åtgärder kan återanvändas.
Definiera en ny åtgärdsklass så här:
~~~
[php]
class UpdateAction extends CAction
{
public function run()
{
// place the action logic here
}
}
~~~
För att kontrollern skall bli varse denna åtgärd, åsidosätter vi den ärvda
[actions()|CController::actions]-metoden i kontrollerklassen:
~~~
[php]
class PostController extends CController
{
public function actions()
{
return array(
'edit'=>'application.controllers.post.UpdateAction',
);
}
}
~~~
Ovan används sökvägsalias `application.controllers.post.UpdateAction` för att
specificera att åtgärdsklassens fil är `protected/controllers/post/UpdateAction.php`.
Med hjälp av klassbaserade åtgärder kan en applikation organiseras modulärt.
Till exempel kan följande katalogstruktur användas för att organisera kontrollrar och
åtgärdsklasser:
~~~
protected/
controllers/
PostController.php
UserController.php
post/
CreateAction.php
ReadAction.php
UpdateAction.php
user/
CreateAction.php
ListAction.php
ProfileAction.php
UpdateAction.php
~~~
### Knyta parametrar till Action
Med start i version 1.1.4 har Yii försetts med stöd för automatisk koppling av
parametrar till kontrolleråtgärder. Det innebär att en kontrollers åtgärdsmetod
kan definiera namngivna parametrar vars värde automatiskt kommer att hämtas från
`$_GET` av Yii.
För fördjupad inblick i denna finess, antag att vi behöver skriva en `create`-åtgärd
för `PostController`. Åtgärden behöver två parametrar:
* `category`: ett heltal som indikerar det kategori-ID under vilket den nya postningen skall skapas
* `language`: en sträng som indikerar vilken språkkod den nya postningen skall höra till.
Vi kan komma fram till följande trista kod för ändamålet att hämta in de erforderliga
parametervärdena från `$_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';
// ... fun code starts here ...
}
}
~~~
Med användning av finessen åtgärdsparametrar kan vi lösa uppgiften mer bekvämt:
~~~
[php]
class PostController extends CController
{
public function actionCreate($category, $language='en')
{
// ... fun code starts here ...
}
}
~~~
Märk att vi lägger till två parametrar till åtgärdsmetoden `actionCreate`.
Namnen på dessa parametrar måste exakt stämma överens med de vi förväntar oss
från `$_GET`. Parametern `$language` erhåller standardvärdet `en` i händelse av att
användaren inte tillhandahåller en sådan parameter i sin request. Eftersom `$category`
inte är försett med ett standardvärde, kommer en [CHttpException] att genereras om användaren inte
tillhandahåller parametern `category` i `$_GET`.
Med start från version 1.1.5, kan Yii även detektera åtgärdsparametrar av arraytyp.
Detta sker med hjälp av PHP typledtrådar vars syntax ser ut som följer:
~~~
[php]
class PostController extends CController
{
public function actionCreate(array $categories)
{
// Yii ser till att $categories kommer att vara en array
}
}
~~~
Det vill säga, vi inflikar nyckelordet `array` före `$categories` i metodens parameterlista.
Genom detta kommer `$_GET['categories']`, om denna är en enkel sträng,
att konverteras till en array med strängen som innehåll.
> Note|Märk: Om en parameter deklareras utan typledtråden `array`, innebär detta att parametern
> mäste vara skalär (dvs inte en array). Om, i detta fall, en arrayparameter förmedlas via
> `$_GET` leder det till en HTTP-exception.
Filter
------
Filter är ett stycke kod som konfigureras att exekvera före och/eller efter
exekvering av en kontrolleråtgärd. Exempel: ett filter för
tillträdeskontroll kan köras för att säkerställa att användaren är autenticerad
innan en begärd åtgärd utförs; ett prestandafilter kan användas för att
mäta tidåtgång vid exekvering av en åtgärd.
En åtgärd kan ha flera filter. Filtren körs i den ordning de förekommer i
filterdeklarationen. Ett filter kan förhindra exekvering av åtgärden såväl som
återstående ej exekverade filter.
Ett filter kan definieras som en metod i kontrollerklassen. Metoden namn måste
börja med `filter`. Exempelvis förekomsten av en metod `filterAccessControl`
definierar ett filter med namnet `accessControl`. Signaturen för filtermetoden måste vara:
~~~
[php]
public function filterAccessControl($filterChain)
{
// call $filterChain->run() to continue filtering and action execution
}
~~~
där `$filterChain` är en instans av [CFilterChain] vilken representerar begärd
åtgärds filterlista. I filtermetoden kan vi anropa `$filterChain->run()` för att
fortsätta med exekvering av övriga filter samt åtgärd.
Ett filter kan också vara en instans av [CFilter] eller en nedärvd klass.
Följande kod definierar en ny filterklass:
~~~
[php]
class PerformanceFilter extends CFilter
{
protected function preFilter($filterChain)
{
// logic being applied before the action is executed
return true; // false if the action should not be executed
}
protected function postFilter($filterChain)
{
// logic being applied after the action is executed
}
}
~~~
Åtgärder förses med filter genom att den ärvda metoden `CController::filters()`
omdefinieras . Metoden skall returnera en array av filterkonfigurationer.
Exempel:
~~~
[php]
class PostController extends CController
{
......
public function filters()
{
return array(
'postOnly + edit, create',
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
~~~
Ovanstående kod specificerar två filter: `postOnly` och `PerformanceFilter`.
`postOnly`-filtret är metodbaserat (den motsvarande filtermetoden är redan
definierad i [CController]); medan däremot `PerformanceFilter`-filtret är
objektbaserat. Sökvägsalias `application.filters.PerformanceFilter` specificerar
att filtrets klassfil är `protected/filters/PerformanceFilter`. En array används
för att konfigurera `PerformanceFilter` så att propertyvärdena för
filterobjektet kan initialiseras. I exemplet initialiseras propertyn `unit` i
`PerformanceFilter` till `'second'`.
Genom användning av plus- och minusoperatorerna kan vi specificera vilka
åtgärder filtret skall eller inte skall tillämpas på. I exemplet ovan tillämpas
filtret `postOnly` på åtgärderna `edit` och `create`, medan `PerformanceFilter`
tillämpas på alla åtgärder UTOM `edit` och `create`. Om varken plus eller minus
förekommer i filterkonfigurationen tillämpas filtret på alla åtgärder.
<div class="revision">$Id: basics.controller.txt 2672 2010-11-22 19:13:16Z qiang.xue $</div>