0 follower

Controller

En controller Àr en instans av CController eller av en klass som utökar CController. Den skapas av applikationsobjektet till följd av en request frÄn anvÀndare. NÀr en kontroller körs utförs 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. Normalt har standardÄtgÀrden namnet index. Detta kan Àndras medelst den publikt tillgÀngliga instansvariablen CController::defaultAction.

Följande kod definierar en site-controller, en index-ÄtgÀrd (standardÄtgÀrden), samt en contact-ÄtgÀrd:

class SiteController extends CController
{
    public function actionIndex()
    {
        // ...
    }
 
    public function actionContact()
    {
        // ...
    }
}

1. Route ¶

Kontroller och ÄtgÀrd identifieras genom ID:n. Ett kontroller-ID har formatet path/to/xyz motsvarande kontrollerklassfilen protected/controllers/path/to/XyzController.php, dÀr ledet xyz skall ersÀttas med aktuella namn (exempelvis motsvarar post 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.

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 post-kontrollern och dess edit-ÄtgÀrd.

MÀrk: Som standard Àr route skiftlÀgesberoende. Route kan 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.

En applikation kan 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 statisk 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 mappas till kontrollerklassen UserController med klassfilen protected/controllers/admin/UserController.php. Om klassfilen inte kan hittas ges en 404 CHttpException.

Om moduler anvÀnds, À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 modulen 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

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 att Ă„skĂ„dliggöra 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:

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:

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:

class PostController extends CController
{
    public function actionCreate(array $categories)
    {
        // Yii ser till att $categories Àr 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.

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.

Med start frÄn version 1.1.7, fungerar automatisk koppling av parametrar Àven för klassbaserade ÄtgÀrder. NÀr metoden run() i en ÄtgÀrdsklass deklareras med parametrar, kommer dessa att erhÄlla vÀrden frÄn motsvarande namngivna request-parametrar. Till exempel,

class UpdateAction extends CAction
{
    public function run($id)
    {
        // $id erhÄller vÀrde frÄn $_GET['id']
    }
}

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. Metodens namn mÄste börja med filter. Exempelvis en metod filterAccessControl definierar ett filter med namnet accessControl. Filtermetoden mÄste ha korrekt signatur:

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 en filtermetod 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 filtret 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.

Found a typo, or you think this page needs improvement?
Edit it on GitHub !