Het Zend_Controller
systeem werd gebouwd met uitbreiding
in het hoofd, ofwel door het onderklassen van de bestaande
klassen of door het schrijven van nieuwe klassen die de interfaces
van Zend_Controller_Router_Interface
en Zend_Controller_Dispatcher_Interface
implementeren.
Mogelijke redenen om een nieuwe router of dispatcher te implementeren kunnen zijn:
Het bestaande URI routing systeem is niet toepasbaar om één of andere reden, zoals de integratie in een bestaande website die zijn eigen conventies voor routing heeft en die niet overeenkomen met het routing systeem van het Zend Framework.
Je moet een routing systeem implementeren voor iets volledig anders. De Zend_Controller_Router
klasse kan alleen URIs afhandelen. Het is mogelijk --en waarschijnlijk-- dat je het MVC patroon
wil gebruiken om een ander type programma te ontwikkelen, zoals een console toepassing. In het
geval van een console toepassing zou een aangepaste router argumenten van de commandoregel moeten kunnen
verwerken om de route te determineren.
Het mechanisme dat door Zend_Controller_Dispatcher
wordt verstrekt is niet toepasbaar. De
standaard configuratie neemt een overeenkomst aan die zegt dat controllers klassen zijn en acties
methodes van die klassen. Er zijn evenwel vele andere strategiën om dit te doen. Eén voorbeeld zou
zijn waar de controllers mappen zijn en de acties bestanden in die mappen.
Je wil bijkomende mogelijkheden verstrekken die door al je controllers worden geërfd. Bijvoorbeeld,
Zend_Controller_Action
kan niet standaard geïntegreerd worden met Zend_View
.
Wat je evenwel wèl kan doen is je eigen controller aanpassen zodat die kan integreren met
Zend_View
. Die gebruiken vermijdt het wijzigen van de verstrekte
Zend_Controller_Router
of Zend_Controller_Dispatcher
.
Wees voorzichtig met het wijzigen van belangrijke delen van het systeem, en in het bijzonder de dispatcher. Een van
de voordelen van Zend_Controller
is dat het algemene overeenkomsten vestigt voor het bouwen van
toepassingen. Indien teveel van dit standaard gedrag wordt gewijzigd, zal een deel van deze voordelen verloren
gaan. Er zijn evenwel vele verschillende benodigdheden en één enkele oplossing is niet ideaal voor alle situaties. De
vrijheid om te wijzigen is dus verstrekt indien nodig.
Bij het onderklassen van een Zend_Controller klasse is het sterk aangeraden de volgende overeenkomsten te respecteren bij de benaming en het opslaan van bestanden. Door dit te doen verzeker je ervan dat een andere programmeur die het Zend Framework kent gemakkelijk je project kan begrijpen.
Klassen die inbegrepen zijn in het Zend Framework volgen een overeenkomst waarbij elke klasse geprefixed wordt door "Zend_". Dat is de prefix. We raden sterk aan dat jij al jouw klassen op een gelijkaardige wijze benoemd, bv: als je bedrijf Widget NV noemt, zou de prefix "Widget_" kunnen zijn.
Zend_Controller
klassen worden als volgt in de bibliotheekmap opgeslaan:
/library /Zend /Controller Action.php Dispatcher.php Router.php
Bij het onderklassen van Zend_Controller
klassen is het aangeraden dat de nieuwe
klassen opgeslagen worden in een gelijkaardige structuur onder jouw prefix. Dat maakt het
gemakkelijk om ze te vinden voor iemand gedurende dat leerprocess dat het nakijken van de
code van jouw project is.
Bijvoorbeeld, een project Widget NV dat alleen een aangepaste router implementeerd zou op het volgende kunnen lijken:
/library /Zend /Widget /Controller Router.php README.txt
Merk in dit voorbeeld op dat de Widget/Controller/
map de Zend/Controller/
weerspiegelt
waar dat ook maar enigzins mogelijk is. In dit geval verstrekt het een Widget_Controller_Router
klasse die een onderklasse of een vervanging is voor Zend_Controller_Router
en die de
Widget_Controller_Router_Interface
implementeert.
Merk ook op in het voorbeeld hierboven dat een README.txt
bestand is opgeslaan in
Widget/Controller
. Zend moedigt je sterk aan je projecten te documenteren door
afzonderlijke tests en documentatie te verstrekken voor je klanten. We moedigen je ook sterk aan
een eenvoudig README.txt
bestand te plaatsen in de map om kort je veranderingen
uit te leggen en hoe ze werken.
De interface Zend_Controller_Router_Interface
verstrekt een definitie voor één enkele methode:
<?php /** * @param Zend_Controller_Dispatcher_Interface * @throws Zend_Controller_Router_Exception * @return Zend_Controller_Dispatcher_Token|boolean */ public function route(Zend_Controller_Dispatcher_Interface $dispatcher); ?>
Routing gebeurt slecht één enkele keer: wanneer het verzoek voor het eerst door het systeem wordt ontvangen.
Het doel van de router is een Zend_Controller_Dispatch_Token
aan te maken dat een controller
en een actie van die controller definieert. Dit wordt dan doorgegeven aan de dispatcher. Indien het niet
mogelijk is een route naar een dispatch token te mappen (nonsensical route) dan moet er een boolean,
FALSE
worden teruggestuurd.
Sommige routers kunnen dynamische elementen verwerken en hebben een manier nodig om de determineren of het
aldus gegenereerde token inderdaad dispatchbaar is voordat het wordt teruggestuurd. Om deze reden ontvangt
de router de object handle van de dispatcher als enig argument voor zijn route()
methode.
De dispatcher verstrekt een methode, isDispatchable()
om dit te testen.
Zend_Controller_Front
zal eerst de router benaderen om een eerste dispatch token te ontvangen en
zal dit doorgeven aan de dispatcher. De dispatcher zal de actie (de controller instantiëren, zijn actie
oproepen) dispatchen en dan ofwel een boolean, FALSE, teruggeven, of een ander dispatch token.
Zend_Controller_Front
roept herhaaldelijk de dispatcher op tot deze geen dispatch token meer terug
stuurt. Dit staat bekend als de dispatch loop. Het laat toe acties opeenvolgend te verwerken tot al het werk
gedaan is.
De Zend_Controller_Dispatcher_Interface
interface verstrekt definities voor twee methodes:
<?php /** * @param Zend_Controller_Dispatcher_Token $route * @return boolean */ public function isDispatchable(Zend_Controller_Dispatcher_Token $route); ?>
isDispatchable()
gaat na of een dispatch token gedispatched kan worden. Indien dat zo is geeft het
TRUE
terug. Anders geeft het FALSE
terug. In het geval van de standaard implementatie,
Zend_Controller_Dispatcher
, betekent dit dat het controller bestand bestaat, dat de klasse in het
bestand bestaat en dat de actiemethode in de klasse bestaat.
<?php /** * @param Zend_Controller_Dispatcher_Token $route * @return Zend_Controller_Dispatcher_Token|boolean */ public function dispatch(Zend_Controller_Dispatcher_Token $route); ?>
dispatch()
is waar het echte werk wordt gedaan. Deze methode moet de actie van de controller
uitvoeren. Het moet ofwel een dispatch token teruggeven of een boolean, FALSE, om aan te geven dat er geen
werk meer te doen is.