Migration von vorhergehenden Versionen
Die API der MVC Komponenten hat sich mit der Zeit
verändert. Wer Zend Framework bereits in einer früheren Version verwendet hat, folgt dem
Leitfaden unten, damit die Skripte die neue Archtitekur verwenden.
Migratiion von 1.7.x zu 1.8.0 oder neuerÄnderungen der Standard Route
Da übersetzte Segmente in der neuen Standard Route eingeführt wurden, ist das
'@' Zeichen kein spezielles Zeichen am Begin eines Segments
der Route. Um es trotzdem in einem statischen Segment verwenden zu können, muß es
durch das Voranstellen eines zweiten '@' Zeichens escapt
werden. Die selbe Regel trifft für das ':' Zeichen zu:
Migration von 1.6.x zu 1.7.0 oder neuerÄnderungen im Dispatcher Interface
Benutzer haben uns darauf aufmerksam gemacht das
Zend_Controller_Action_Helper_ViewRenderer Methoden auf der
abstrakten Dispatcher Klasse verwendet hat die nicht im Dispatcher Interface waren.
Die folgenden Methoden wurden hinzugefügt um sicherzustellen das eigene Dispatcher
weiterhin mit den ausgelieferten Implementierungen funktionieren:
formatModuleName(): sollte verwendet werden um
einen rohen Controllernamen zu nehmen, wie den einen der in einem
Anfrageobjekt gepackt ist, und Ihn in einen richtigen Klassennamen zu
reformatieren den eine Klasse, die
Zend_Controller_Action erweitert, verwenden würde
Migration von 1.5.x zu 1.6.0 oder neuerÄnderungen im Dispatcher Interface
Benutzer haben uns darauf aufmerksam gemacht das sowohl
Zend_Controller_Front als auch
Zend_Controller_Router_Route_Module Methoden des Dispatchers
verwenden die nicht im Dispatcher Interface waren. Wir haben jetzt die folgenden
drei Methoden hinzugefügt um sicherzustellen das eigene Dispatcher weiterhin mit der
ausgelieferten Implementation arbeiten:
getDefaultModule(): Sollte den Namen des
Standardmoduls zurückgeben.
getDefaultControllerName(): Sollte den Namen des
Standardcontrollers zurückgeben.
getDefaultAction(): Sollte den Namen der
Standardaktion zurückgeben.
Migration von 1.0.x zu 1.5.0 oder neuer
Obwohl die meisten grundsätzlichen Funktionalitäten die gleichen bleiben und alle
dokumentierten Funktionalitäten die gleichen bleiben gibt es doch ein spezielles
undokumentiertes "Feature" das geändert wurde.
Wenn URLs geschrieben werden besteht der dokumentierte Weg darin die
Aktionsnamen camelCased mit einem Trennzeichen zu schreiben; diese sind normalerweise
'.' oder '-', können aber im Dispatcher konfiguriert werden. Der Dispatcher ändert den
Aktionsnamen intern auf Kleinschreibung und verwendet diese Trennzeichen um die
Aktionsmethode wieder zu bauen indem er sie camelCase schreibt. Trotzdem, weil
PHP Funktionen nicht unabhängig von der Schreibweise sind,
könnte man URLs mit camelCase schreiben und der
Dispatcher würde diese auf den gleichen Platz auflösen. Zum Beispiel, 'camel-cased'
würde durch den Dispatcher zu 'camelCasedAction' werden; trotzdem, durch den Fall der
unabhängigen Schreibweise in PHP, würden beide die selbe Methode
ausführen.
Das führt zu Problemen mit dem ViewRenderer wenn View Skripte aufgelöst werden. Der
kanonische, dokumentierte Weg besteht darin das alle Trennzeichen zu Bindestrichen
umgewandelt und die Wörter kleingeschrieben werden. Das erzeugt eine semantische
Bindung zwischen Aktionen und View Skripten, und die Normalisierung stellt sicher
das die Skripte gefunden werden. Trotzdem, wenn die Aktion 'camelCased' aufgerufen und
aufgelöst wird, ist das Trennzeichen nicht mehr vorhanden, und der ViewRenderer
versucht einen anderen Ort aufzulösen -- camelcased.phtml statt
camel-cased.phtml.
Einige Entwickler hängen an diesem "Feature", welches nie angedacht war. Verschiedene
Änderungen im 1.5.0 Baum, führen dazu das der ViewRenderer diese Pfade nicht länger
auflöst; die semantische Bindung wird nun erzwungen. Ale erstes, erzwingt der
Dispatcher nun die Groß-/Kleinschreibung in Aktionsnamen. Das bedeutet dass das
hinleiten zu eigenen Aktionen über die URL durch Verwendung von camelCase nicht länger
auf die gleiche Methode aufgelöst wird wie mit Trennzeichen (z.B. 'camel-casing').
Das führt dazu das der ViewRenderer jetzt nur mehr zeichen-getrennte Aktionen
honoriert wenn er View Skripte auflöst.
´
Wenn man findet das man auf dieses "Feature" nicht verzichten kann gibt es mehrere
Optionen:
Beste Option: Die View Skripte umbenennen. Vorteile: zukünftige Kompatibilität.
Nachteile: Wenn man viele View Skripte hat die auf dem vorigen aufbauen führt
das, unerwarteter Weise, zu vielen Umbenennungen die durchgeführt werden müssen.
Zweitbeste Option: Der ViewRenderer delegiert nun die Auflösung von View
Skripten zu Zend_Filter_Inflector; man kann die Regeln
des Inflectors ändern damit er nicht länger die Wörter der Aktion mit einem
Bindestrich trennt:
getInflector();
$inflector->setFilterRule(':action', array(
new Zend_Filter_PregReplace(
'#[^a-z0-9' . preg_quote(DIRECTORY_SEPARATOR, '#') . ']+#i',
''
),
'StringToLower'
));
]]>
Der obige Code ändert den Inflector so, das er Wörter nicht länger mit einem
Bindestrich trennt; Es kann auch gewünscht sein den 'StringToLower' Filter zu
entfernen man die aktuellen View Skripte camelCased benannt haben
will.
Wenn die Umbenennung der View Skripte zu aufwendig oder Zeitintensiv ist, dann
ist das die beste Option wenn man die Zeit hierfür findet.
Die am wenigsten zu empfehlende Option: Man kann den Dispatcher dazu zwingen
camelCase Aktionsnamen mit einem neuen Front Controller Flag
useCaseSensitiveActions zu bearbeiten:
setParam('useCaseSensitiveActions', true);
]]>
Das erlaubt es camelCase in der URL zu verwenden uns es trotzdem auf die
gleiche Aktion aufzulösen wie wenn Trennzeichen verwendet worden wären. Das
bedeutet dass das Originale Problem trotzdem durchschlägt; es kann notwendig
sein die zweite Option von oben zusätzlich zu verwenden um sicherzustellen
das die Dinge in allen Variationen funktionieren.
Man sollte auch beachten das die Verwendung dieses Flags eine Notiz auslöst,
das dessen Verwendung nicht mehr durchgeführt werden sollte.
Migration von 0.9.3 nach 1.0.0RC1 oder neuer
Die prinzipiellen Änderungen die durch 1.0.0RC1 angeboten werden sind die Einführung und
standardmäßige Aktivierung des
ErrorHandler
Plugins und den
ViewRenderer
Aktionhelfer. Bitte lies die Dokumentation jedes einzelnen gründlich um zu sehen wie sie
arbeiten und welchen Effekt Sie auf die eigene Anwendung haben können.
Der ErrorHandler Plugin läuft wärend der
postDispatch() Prüfung auf Ausnahmen, und leitet zu einem
spezifizierten Fehlerhandler Controller weiter. Solch ein Controller sollte in der
eigenen Anwendung inkludiert werden. Er kann deaktiviert werden durch das setzen des
Frontcontroller Parameters noErrorHandler:
setParam('noErrorHandler', true);
]]>
Der ViewRenderer Aktionhelfer automatisiert die Injizierung der
View in den Aktioncontroller genauso wie das autorendern von Viewskripten basierend auf
die aktuelle Aktion. Das primäre Problem dem man begegnen kann ist, wenn man Aktionen
hat die keine View Skripte rendern und weder vorwärts- noch weiterleiten, da der
ViewRenderer versucht ein View Skript zu Rendern basierend auf
dem Aktionnamen.
Es gibt verschiedene Strategien die man anwenden kann um den eigenen Code upzudaten. In
kurzer Form, kann man global den ViewRenderer im eigenen
Frontcontroller Bootstrap vor dem Abarbeiten ausschalten:
setParam('noViewRenderer', true);
]]>
Trotzdem ist es keine gute Langzeitstrategie, da es auch bedeutet das man mehr Code
schreiben muß.
Wenn man bereit ist damit zu beginnen die ViewRenderer
Funktionalität zu verwenden, gibt es verschiedene Dinge die man im eigenen
Controllercode beachten muß. Zuerst muß auf die Aktionmethoden (die Methoden die mit
'Action' enden) geachtet werden, und ausgesucht werden was eine jede machen soll. Wenn
nichts vom folgenden passiert, muß man Änderungen durchführen:
Aufruf von $this->render();Aufruf von $this->_forward();Aufruf von $this->_redirect();Aufruf des Redirector Aktionhelfers
Die einfachste Änderung ist das Ausschalten des Auto-Rendering für diese Methode:
_helper->viewRenderer->setNoRender();
]]>
Wenn man herausfindet das keine der eigenen Aktionmethoden rendern, weiterleiten oder
umleiten, wird man voraussichtlich die oben angeführte Zeile in die eigene
preDispatch() oder init() Methode
einfügen wollen:
_helper->viewRenderer->setNoRender()
// .. andere Dinge tun...
}
]]>
Wenn render() aufgerufen wird, und man
die konventionelle Modulare Verzeichnis
Struktur verwendet, wird man den Code ändern wollen um Autorendern zu
Verwenden:
Wenn man mehrere View Skripte in einer einzelnen Aktion rendert muß nichts
geändert werden.
Wenn man einfach render() ohne Argumente aufruft,
können diese Zeilen entfernt werden.
Wenn man render() mit Argumenten aufruft, und danach
nicht irgendeine Bearbeitung durchführt oder mehrere View sktipe rendert, können
diese Aufrufe zu $this->_helper->viewRenderer(); geändert
werden.
Wenn die konventionelle modulare Verzeichnisstruktur nicht verwendet wird, gibt es eine
Vielzahl von Methoden für das Setzen des View Basispfades und der Skript
Pfadspezifikationen so das man den ViewRenderer verwenden kann.
Bitte lies die ViewRenderer
Dokumentation für Informationen über diese Methoden.
Wenn ein View Objekt von der Registry verwendet, oder das eigene View Objekt verändert,
oder eine andere View Implementation verwendet wird, dann wird man den
ViewRenderer in diesem Objekt injiziieren wollen. Das kann ganz
einfach jederzeit durchgeführt werden.
Vor dem Verarbeiten einer Frontcontroller Instanz:
Jederzeit wärend des Bootstrap Prozesses:
setView($view);
]]>
Es gibt viele Wege den ViewRenderer zu modifizieren inklusive dem
Setzen eines anderen View Skripts zum Rendern, dem Spezifizieren von Veränderungen für
alle veränderbaren Elemente eines View Skript Pfades (inklusive der Endung), dem
Auswählen eines Antwort-benannten Segments zur Anpassung und mehr. Wenn die
konventionelle modulare Verzeichnisstruktur nicht verwendet wird, kann noch immer eine
andere Pfad Spezifikation mit dem ViewRenderer zugeordnet werden.
Wir empfehlen die Adaptierung des eigenen Codes um den
ErrorHandler und ViewRenderer zu verwenden
da diese neue Kernfunktionalitäten sind.
Migration von 0.9.2 nach 0.9.3 oder neuer
0.9.3 bietet Aktionhelfer neu an.
Als Teil dieser Änderung wurden die folgenden Methoden entfernt da Sie nun im Weiterleitungs
Aktionhelfer inkludiert sind:
setRedirectCode(); wurde umbenannt in
Zend_Controller_Action_Helper_Redirector::setCode().
setRedirectPrependBase(); wurde umbenannt in
Zend_Controller_Action_Helper_Redirector::setPrependBase().
setRedirectExit(); wurde umbenannt in
Zend_Controller_Action_Helper_Redirector::setExit().
Lese die Aktionhelfer Dokumentation
für nähere Informationen über das empfangen und manipulieren von Helfer Objekten und die
Weiterleitungshelfer
Dokumentation für weitere Information über das setzen von
Weiterleitungsoptionen (sowie alternative Methoden des weiterleitens).
Migration von 0.6.0 nach 0.8.0 oder neuer
Durch bisherige Änderungen bleibt die wesentliche Verwendung der MVC
Komponenten gleich:
Dennoch wurde die Verzeichnisstruktur gründliche überarbeitet, verschiedene Komponenten
wurden entfernt und mehrere andere umbenannt und hinzugefügt. Die Änderungen beinhalten:
Zend_Controller_Router wurde entfernt für den Rewrite
Router entfernt.
Zend_Controller_RewriteRouter wurde in
Zend_Controller_Router_Rewrite umbenannt und zum Standard
Router befördert, der mit dem Framework ausgeliefert wird;
Zend_Controller_Front wird ihn als Standard verwenden,
wenn kein anderer Router übergeben wird.
Eine neue Route Klasse für die Verwendung mit dem Rewrite Router wurde
eingeführt: Zend_Controller_Router_Route_Module; sie
deckt die Standardrouten ab, die vom MVC verwendet werden
und bietet die Unterstützung für Controller Module.
Zend_Controller_Router_StaticRoute wurde umbenannt in
Zend_Controller_Router_Route_Static.
Zend_Controller_Dispatcher wurde umbenannt in
Zend_Controller_Dispatcher_Standard.
Zend_Controller_Action::_forward()'s Argumente wurden
geändert. Die Signatur ist nun:
$action wird immer benötigt; wenn kein Controller angegeben
wird, wird eine Action im aktuellen Controller angenommen.
$module wird immer ignoriert, es sei denn
$controller wird angegeben. Schließlich werden alle
übergebenen Parameter $params an das Request Objekt
angehängt. Wenn man keinen Controller oder kein Modul angeben, aber dennoch
Parameter übergeben möchte, gibt man einfach NULL für diese
Werte an.
Migration von 0.2.0 oder früher nach 0.6.0
Die grundlegende Verwendung der MVC Komponenten hat sich nicht
verändert; man kann immer noch das folgende machen:
addRoute('user',
'user/:username',
array('controller' => 'user', 'action' => 'info')
);
/* -- Setze ihn im Controller -- */
$ctrl = Zend_Controller_Front::getInstance();
$ctrl->setRouter($router);
/* -- Setze da Controller Verzeichnis und starte die Verarbeitung -- */
$ctrl->setControllerDirectory('/path/to/controllers');
$ctrl->dispatch();
]]>
Wir empfehlen die Verwendung des Response Objektes, um Inhalte und Header zu sammeln.
Dies erlaubt den flexibleren Wechsel von Ausgabeformaten (z.B. JSON
oder XML statt XHTML) in deiner Applikation.
Standardmäßig verarbeitet dispatch() die Antwort, sendet
Header und gibt die Inhalte aus. Man kann den Front Controller auch auffordern, die
Antwort durch returnResponse() zurückzugeben und die Antwort
dann auf eigene Weise ausgeben. Eine zukünftige Version des Front Controllers könnte
die Verwendung des Response Objektes durch Output Buffering erzwingen.
Es gibt viele weitere zusätzliche Funktionalitäten, welche die vorherige
API erweitern. Diese sind in der Dokumentation aufgeführt.
Die meisten Änderungen, die man beachten muss, betreffen das Erweitern der diversen
Komponenten. Die wichtigsten davon sind:
Zend_Controller_Front::dispatch() fängt standardmäßig
die Ausnahmen im Response Objekt ab und gibt sie nicht aus, um sicherzugehen,
dass keine sensitiven Systeminformationen ausgegeben werden. Man kann dies auf
mehrere Arten überschreiben:
Setzen von throwExceptions() im Front
Controller:
throwExceptions(true);
]]>
Setzen von renderExceptions() im Response
Objekt:
renderExceptions(true);
$front->setResponse($response);
$front->dispatch();
// oder:
$front->returnResponse(true);
$response = $front->dispatch();
$response->renderExceptions(true);
echo $response;
]]>Zend_Controller_Dispatcher_Interface::dispatch()
akzeptiert und gibt nun ein Anfrage Objekt anstelle eines
Dispatcher Token zurück.
Zend_Controller_Router_Interface::route()
akzeptiert und gibt nun ein Anfrage Objekt anstelle eines
Dispatcher Token zurück.
Zend_Controller_Action Änderungen beinhalten:
Der Konstruktur akzeptiert nun genau drei Argumente,
Zend_Controller_Request_Abstract$request,
Zend_Controller_Response_Abstract$response, und
Array$params (Optional).
Zend_Controller_Action::__construct()
verwendet diese, um die Request, Response und invokeArgs Eigenschaften
für das Objekt zu setzen, und beim Überschreiben des Konstrukturs
sollte man dies ebenfalls tun. Besser ist es, die
init() Methode zu verwenden, um jedwede
Instanzkonfiguration durchzuführen, weil diese Methode als letzte
Methode des Konstrukturs aufgerufen wird.
run() ist nicht länger als final definiert,
wird aber auch nicht länger vom Front Controller verwendet; sein
einziger Zweck ist, dass die Klasse auch als Page Controller verwendet
werden kann. Sie nimmt nun zwei optionale Argument an, ein
Zend_Controller_Request_Abstract$request und ein
Zend_Controller_Response_Abstract$response.
indexAction() muss nicht mehr länger definiert
werden, aber wird als Standardaktion empfohlen. Dies erlaubt dem
RewriteRouter und den Action Controllern andere Standardaktionsmethoden
zu definieren.
__call() sollte überschrieben werden, um jede
undefinierte Aktion automatisch verarbeiten zu können.
_redirect() nimmt nun ein optionales zweites
Argument entgegen, den HTTP Code, der mit dem
Redirect zurückgegeben werden soll, und ein optionales drittes Argument
$prependBase, das angibt, dass die im Request Objekt
registrierte Basis URL der übergebenen URL voran
gestellt werden soll.
Die $_action Eigenschaft wird nicht mehr gesetzt.
Diese Eigenschaft war ein
Zend_Controller_Dispatcher_Token, der in der
aktuellen Inkarnation nicht mehr länger existiert. Der einzige Zweck
des Tokens war, Informationen über angeforderte Controller, Aktion und
URL Parameter bereit zu stellen. Diese Infrmationen
ist nun im Request Objekt verfügbar und kann wie folgt abgerufen
werden:
_action->getControllerName().
// Das Beispiel unten verwendet getRequest(), obwohl man auch direkt auf die
// $_request Eigenschaft zugreifen kann; die Verwendung von getRequest() wird
// empfohlen, da eine Elternklasse den Zugriff auf das Request Objekt
// überschreiben könnte
$controller = $this->getRequest()->getControllerName();
// Hole den angeforderten Aktionsnamen
// Der Zugriff erfolgte bisher über: $this->_action->getActionName().
$action = $this->getRequest()->getActionName();
// Hole die Anfrageparameter
// Dies hat sich nicht verändert; die _getParams() und _getParam()
// Methoden leiten nun einfach auf das Request Objekt weiter.
$params = $this->_getParams();
// fordere den 'foo' Parameter an und verwende
// 'default', wenn kein Standardwert gefunden werden kann
$foo = $this->_getParam('foo', 'default');
]]>noRouteAction() wurde entfernt. Der geeignete
Weg, um nicht vorhandene Aktionsmethoden abzufangen, wenn man sie an
eine Standardaktion weiter leiten möchte, sollte die Verwendung von
__call() sein:
defaultAction();
}
throw new Zend_Controller_Exception('Invalid method called');
}
]]>Zend_Controller_RewriteRouter::setRewriteBase() wurde
entfernt. Stattdessen soll
Zend_Controller_Front::setBaseUrl() verwendet werden
(oder Zend_Controller_Request_Http::setBaseUrl(), wenn
die Request Klasse verwendet wird).
Zend_Controller_Plugin_Interface wurde durch
Zend_Controller_Plugin_Abstract ersetzt. Alle Methoden
nehmen nun ein Request Objekt
statt eines Dispatcher Tokens entgegen bzw. geben es zurück.