7.3. Onderklassen
Terug | Hoofdstuk 7. Zend_Controller | Volgende

## 7.3. Onderklassen

### 7.3.1. Inleiding

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.

### 7.3.2. Overeenkomsten

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.

#### 7.3.2.1. Prefix

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.

#### 7.3.2.2. Mappen Lay-out

`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.

### 7.3.3. Router Interface

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.

### 7.3.4. Dispatcher Interface

`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.

Terug | Omhoog | Volgende
7.2. Om te beginnen | Begin | 7.4. Provided Subclasses