0 follower

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.

Nedan visas minimal kod som erfordras i en kontrollerklass. Eftersom denna klass inte definierar nÄgon ÄtgÀrd genererar den en exception vid anrop.

class SiteController extends CController
{
}

1. 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.

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.

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 och action map anvÀnder gemener i sina nyckelvÀrden.

Fr o m version 1.0.3 kan en applikation innehÄlla moduler. 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.

2. 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 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.

3. 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:

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()-metoden i kontrollerklassen:

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

4. 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:

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:

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:

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.