Ein Controller
ist eine Instanz vom Typ CController oder dessen
Kindklassen. Er wird von der Applikation erzeugt, wenn eine Benutzeranfrage
dafür vorliegt. Wenn ein Controller gestartet wird,
führt er die angeforderte Action aus, welche in der Regel die benötigten Models
einbindet und einen passenden View rendert (sinngem.: machen, darstellen) .
Eine Action
ist in ihrer einfachsten Form lediglich eine Klassenmethode des Controllers,
deren Name mit action
anfängt.
Ein Controller hat eine Standardaction. Wenn im Benutzer-Request nicht
festgelegt wurde, welche Action ausgeführt werden soll, wird die
Standardaction ausgeführt. Als Vorgabewert ist die Standardaction index
definiert. Sie kann durch Setzen der CController::defaultAction verändert
werden.
Unten steht der Minimalcode, den ein Controller benötigt. Da dieser Controller keine Action enthält, würde bei seinem Aufruf eine Exception ausgelöst.
class SiteController extends CController
{
}
Controller und Actions werden durch ihre IDs identifiziert. Eine Controller-ID
hat das Format pfad/zu/xyz
, was der Controller-Datei
protected/controllers/pfad/zu/XyzController.php
entspricht, wobei das Kürzel
xyz
durch echte Namen ersetzt werden sollte (z.B. entspricht post
der Datei protected/controllers/PostController.php
). Die Action-ID ist der
Name der Action-Methode ohne die action
-Präfix. Wenn eine Controller-Klasse
z.B. eine Methode namens actionEdit
enthält, entspricht dies der Action-ID
edit
.
Hinweis: Vor Version 1.0.3 war das Format der Controller-ID
pfad.zu.xyz
stattpfad/zu/xyz
.
Eine bestimmte Controller-/Action-Kombination wird von Benutzern in Form einer
sogenannten Route angefordert. Eine Route setzt sich aus Controller- und
Action-ID zusammen, getrennt durch einen Schrägstrich (/). Zum Beispiel bezieht
sich die Route post/edit
auf den PostController
und dessen edit
-Action.
Standardmäßig würde dieser Controller mit dieser Action über die URL
http://hostname/index.php?r=post/edit
aufgerufen.
Hinweis: Normalerweise spielt die Groß-/Kleinschreibung bei Routen eine Rolle. Seit Version 1.0.1 ist es möglich, dies zu deaktivieren, indem man CUrlManager::caseSensitive in der Anwendungskonfiguration auf false setzt. Falls Groß-/Kleinschreibung aktiviert ist, stellen Sie bitte sicher, dass Verzeichnisse, die Controller enthalten, kleingeschrieben werden und dass sowohl controllerMap als auch actionMap Schlüssel in Kleinbuchstaben verwenden.
Eine Controller-Instanz wird dann erzeugt, wenn CWebApplication einen einkommenden Request bearbeitet. Bei gegebener ID des Controllers geht die Applikation nach folgenden Regeln vor, um die Klasse und den Ort der Klassendatei zu bestimmen:
Wenn CWebApplication::catchAllRequest konfiguriert wurde, wird der entsprechende Controller gemäß dieses Wertes erstellt und die vom Benutzer angegebene Controller-ID ignoriert. Dies wird hauptsächlich verwendet, um die Anwendung in den Wartungsmodus zu schalten und eine statische Hinweisseite anzuzeigen.
Wenn die ID in CWebApplication::controllerMap enthalten ist, wird die entsprechende Controller-Konfiguration verwendet, um die Controller-Instanz zu erstellen.
Falls die ID im Format 'pfad/zu/xyz'
vorliegt, wird von der
Controller-Klasse XyzController
in der Datei
protected/controllers/pfad/zu/XyzController.php
ausgegangen. Die
Controller-ID admin/user
würde zum Beispiel in die Controller-Klasse
UserController
und die Datei protected/controllers/admin/UserController.php
aufgelöst werden. Falls die Klassendatei nicht existiert, wird eine
404-CHttpException ausgelöst.
Falls Module verwendet werden (seit Version 1.0.3 verfügbar), unterscheidet sich der obige Prozess etwas. Die Anwendung prüft in diesem Fall, ob sich die ID auf einen Controller eines Moduls bezieht. Falls ja, erzeugt sie zunächst die Modulinstanz und danach die Controllerinstanz.
Wie erwähnt, kann eine Action als eine Methode definiert werden, die mit
dem Wort action
beginnt. Eine weitere, fortgeschrittenere Möglichkeit besteht
darin, eine Action-Klasse zu definieren und den Controller zu bitten, diese
auf Anfrage zu instanziieren. Dadurch können Actions mehrfach eingesetzt werden,
was die Wiederverwendbarkeit erhöht.
Um eine neue Action-Klasse zu definieren, verfahren Sie wie folgt:
class UpdateAction extends CAction
{
public function run()
{
// Hier steht die Programmlogik der Action
}
}
Damit der Controller die Action kennt, überschreiben wir die actions()-Methode unserer Controller-Klasse:
class PostController extends CController
{
public function actions()
{
return array(
'edit'=>'application.controllers.post.UpdateAction',
);
}
}
Im Beispiel benutzen wir den Pfad-Alias
application.controllers.post.UpdateAction
, um anzugeben, dass sich die
Klassendatei der Action in protected/controllers/post/UpdateAction.php
befindet.
Indem wir klassenbasierte Actions schreiben, können wir unsere Anwendung modular organisieren. So könnte zur Ablage des Codes für die Controller z.B. die folgende Verzeichnisstruktur verwendet werden:
protected/ controllers/ PostController.php UserController.php post/ CreateAction.php ReadAction.php UpdateAction.php user/ CreateAction.php ListAction.php ProfileAction.php UpdateAction.php
Ein Filter ist ein Codeteil, der je nach Konfiguration vor und/oder nach einer Action ausgeführt wird. So könnte z.B. ein Filter für die Zugriffskontrolle aufgerufen werden, um sicherzustellen, dass der Benutzer authentifiziert wurde, bevor dir angeforderte Action ausgeführt wird. Ein Leistungsfilter könnte die Zeit, die eine Action zur Ausführung braucht, messen.
Eine Action kann mehrere Filter haben. Die Filter werden in der Reihenfolge ausgeführt, in der sie in der Filterliste erscheinen. Ein Filter kann die Ausführung der Action sowie der restlichen verbleibenden Filter verhindern.
Ein Filter kann als Klassenmethode eines Controllers definiert werden. Der
Name der Methode muss mit filter
beginnen. Existiert z.B. eine Methode
namens filterAccessControl
, so ist darin ein Filter namens accessControl
definiert. Die Filtermethode muss dieser Signatur entsprechen:
public function filterAccessControl($filterChain)
{
// Rufen Sie $filterChain->run() auf, um mit der Filterung
// fortzufahren bzw. die Action auszuführen.
}
wobei $filterChain
(Filterkette) eine Instanz vom Typ CFilterChain ist,
die die Liste der Filter darstellt, die mit der Action verbunden sind. Innerhalb
der Filtermethode können wir $filterChain->run()
aufrufen, um mit der Filterung
fortzufahren, bzw. am Ende die Action auszuführen.
Ein Filter kann auch einen Instanz vom Typ CFilter oder dessen Kindklassen sein. Der folgende Code definiert eine neue Filterklasse:
class PerformanceFilter extends CFilter
{
protected function preFilter($filterChain)
{
// Programmlogik, die vor der Action ausgeführt wird
return true; // false, wenn die Action nicht ausgeführt werden soll
}
protected function postFilter($filterChain)
{
// Programmlogik, die nach der Action ausgeführt wird
}
}
Um Filter auf Actions anzuwenden, müssen wir die Methode
CController::filters()
überschreiben. Die Methode sollte ein Array von
Filterkonfigurationen zurückliefern. Zum Beispiel
class PostController extends CController
{
......
public function filters()
{
return array(
'postOnly + edit, create',
array(
'application.filters.PerformanceFilter - edit, create',
'unit'=>'second',
),
);
}
}
Der obige Code bestimmt zwei Filter: postOnly
und PerformanceFilter
.
Der postOnly
-Filter ist methodenbasiert (die entsprechende Filtermethode ist
bereits in CController definiert), während der PerformanceFilter
als Objekt vorliegt. Der Pfad-Alias application.filters.PerformanceFilter
legt
fest, dass sich die Datei der Filterklasse in protected/filters/PerformanceFilter
befindet. Wir verwenden ein Array für die Konfiguration von PerformanceFilter
,
um auch gleich die Starteigenschaften des Filterobjekts zu definieren.
Im Beispiel setzen wir die Eigenschaft unit
auf 'second'
.
Durch Plus- und Minusoperatoren können wir bestimmen, auf welche Actions der
Filter angewendet werden soll und auf welche nicht. Oben soll der Filter
postOnly
auf die Actions edit
und create
angewendet werden, wohingegen
PerformanceFilter
für alle Actions AUSSER edit
und create
gilt. Falls
weder Plus noch Minus in der Filterkonfiguration auftauchen, wird der Filter
auf alle Actions angewendet.
Signup or Login in order to comment.