Programmer's Reference Guide
| MVC Ausnahmen |
Migration von vorhergehenden Versionen
Die API der MVC Komponenten hat sich mit der Zeit verändert. Wer das Zend Framework bereits in einer früheren Version verwendet hat, folgt dem Leitfaden unten, damit die Skripte die neue Archtitekur verwenden.
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 das 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:<?php $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $inflector = $viewRenderer->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 Kontroller Flag 'useCaseSensitiveActions' zu bearbeiten:
<?php $front->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 das 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 Kontroller weiter. Solch ein Kontroller
sollte in der eigenen Anwendung inkludiert werden. Er kann deaktiviert werden durch das setzen des
Frontkontroller Parameters noErrorHandler:
<?php
$front->setParam('noErrorHandler', true);
Der ViewRenderer Aktionhelfer automatisiert die Injizierung der View in den Aktionkontroller
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 Frontkontroller Bootstrap vor dem
Abarbeiten ausschalten:
<?php
// Annahme das $front eine Instanz von Zend_Controller_Front ist
$front->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 Kontrollercode 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
RedirectorAktionhelfers
Die einfachste Änderung ist das ausschalten des Auto-Rendering für diese Methode:
$this->_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:
public function preDispatch()
{
// Ausschalten des autorendern vom View Skript
$this->_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 wird man den ViewRenderer in diesem
Objekt injiziieren wollen. Das kann ganz einfach jederzeit durchgeführt werden.
-
Vor dem verarbeiten einer Frontkontroller Instanz:
<?php // Annahme das $view bereits definiert wurde $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view); Zend_Controller_Action_HelperBroker::addHelper($viewRenderer); -
Jederzeit wärend des Bootstrap Prozesses:
<?php $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer'); $viewRenderer->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 inZend_Controller_Action_Helper_Redirector::setCode(). -
setRedirectPrependBase(); wurde umbenannt inZend_Controller_Action_Helper_Redirector::setPrependBase(). -
setRedirectExit(); wurde umbenannt inZend_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:
require_once 'Zend/Controller/Front.php';
Zend_Controller_Front::run('/path/to/controllers');
Dennoch wurde die Verzeichnisstruktur gründliche überarbeitet, verschiedene Komponenten wurden entfernt und mehrere andere umbenannt und hinzugefügt. Die Änderungen beinhalten:
-
Zend_Controller_Routerwurde entfernt für den Rewrite Router entfernt. -
Zend_Controller_RewriteRouterwurde inZend_Controller_Router_Rewriteumbenannt und zum Standard Router befördert, der mit dem Framework ausgeliefert wird;Zend_Controller_Frontwird 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_StaticRoutewurde umbenannt inZend_Controller_Router_Route_Static. -
Zend_Controller_Dispatcherwurde umbenannt inZend_Controller_Dispatcher_Standard. -
Zend_Controller_Action::_forward()'s Argumente wurden geändert. Die Signatur ist nun:final protected function _forward($action, $controller = null, $module = null, array $params = null);$actionwird immer benötigt; wenn kein Controller angegeben wird, wird eine Action im aktuellen Controller angenommen.$modulewird immer ignoriert, es sei denn$controllerwird angegeben. Schließlich werden alle übergebenen Parameter$paramsan 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:
require_once 'Zend/Controller/Front.php';
Zend_Controller_Front::run('/path/to/controllers');
/* -- Erstelle einen Router -- */
$router = new Zend_Controller_RewriteRouter();
$router->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:$front->throwExceptions(true); -
Setzen von
renderExceptions()im Response objekt:$response->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 Das Request Objekt Objekt anstelle eines Dispatcher Token zurück.Zend_Controller_Router_Interface::route()akzeptiert und gibt nun ein Das Request Objekt 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, undarray $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, dieinit()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, einZend_Controller_Request_Abstract $requestund einZend_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
_actionEigenschaft wird nicht mehr gesetzt. Diese Eigenschaft war einZend_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:// Hole den angeforderten Controllernamen // Der Zugriff erfolgte bisher über: $this->_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(); $foo = $this->_getParam('foo', 'default'); // fordere den 'foo' Parameter an und verwende // 'default', wenn kein Standardwert gefunden werden kann -
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:public function __call($method, $args) { // Wenn eine nicht vorhandene 'Action' Methode angefordert wurde, leite auf die Standard // Aktionsmethode um: if ('Action' == substr($method, -6)) { return $this->defaultAction(); } throw new Zend_Controller_Exception('Invalid method called'); }
Zend_Controller_RewriteRouter::setRewriteBase()wurde entfernt. Stattdessen sollZend_Controller_Front::setBaseUrl()verwendet werden (oder Zend_Controller_Request_Http::setBaseUrl(), wenn die Request Klasse verwendet wird).Zend_Controller_Plugin_Interfacewurde durch byZend_Controller_Plugin_Abstractersetzt. Alle Methoden nehmen nun ein Das Request Objekt Objekt statt eines Dispatcher Tokens entgegen bzw. geben es zurück.
| MVC Ausnahmen |
Select a Version
Languages Available
Components
Search the Manual
Navigation
- Programmierer Referenzhandbuch
- Programmierer Referenzhandbuch
- Zend_Controller
- Zend_Controller Schnellstart
- Zend_Controller Grundlagen
- Der Front Controller
- Das Request Objekt
- Der Standard Router: Zend_Controller_Router_Rewrite
- Der Dispatcher
- Action Kontroller
- Action Helfer
- Das Response Objekt
- Plugins
- Eine konventionelle modulare Verzeichnis Struktur verwenden
- MVC Ausnahmen
- Migration von vorhergehenden Versionen
