Weiter zum Inhalt

Das Model und das Zend Framework

Über das MVC Pattern steht ja an anderen Stellen zu Genüge Theoretisches geschrieben. Aber wenn es um die Praxis geht, gibt es sehr wohl Unterschiede.

Bei meinen Expeditionen ins Zend Framework habe ich mir nun einmal angesehen, wie das denn mit dem Model funktioniert.
Nun, wie so oft beim ZF gibt es nicht DEN einen Weg.

Was verstehe ich nun unter einem Model? Nun, bei jedem Controller gibt es verschiedene Actions, die eigene Daten aus der Persistenz benötigen können – natürlich verschieden aufbereitet. Nun – es würde aber komplett dem objektorientierten Design widersprechen, wenn wir jetzt her gehen würden und in jedem Model, zu jedem Controller, gleiche Abfragen redundant immer und immer wieder notieren. Nun, wie passt das nun zusammen?

Hmm, die einfachste Möglichkeit ist, hier noch einmal eine Trennung zu vollziehen. So gibt es dann eine kleine Logik im Model und eine Datenzugriffsklasse (DAO) für jede Tabelle. Es gibt dann ein eigenes Model für jeden Controller. In diesem werden die verschiedenen Daten so aufbereitet, wie sie der Controller benötigt. Für die Datenholung im Model werden dann Data Access Objects genutzt, in welchen die eigentlichen Queries gekapselt sind.

Jetzt gab es aber erstmal genügend Theorie. Auf zur Praxis…

Es soll eine einheitliche Form geben, wie ich in meinen Controllern an das eigene Model komme. Ich könnte jetzt immer in jeder Action ein Objekt bauen. Das würde mit dem Zend Loader auch super funktionieren, aber es wäre nicht wirklich wartbar. Also  implementiere ich eine Methode getModel(), die mir eine gültige Instanz zurück liefert. Diese wird dann aber auch nur einmal instanziiert – eine Art Singleton Pattern also.
Damit wir jetzt nicht immer wieder die gleiche Methode in jedem Controller bauen, erstelle ich eine neue Klasse, welche von Zend_Controller_Action erbt. Diese dient dann als Basisklasse, die die einzelnen Controller konkretisieren.

class hl_Controller_Action extends Zend_Controller_Action {
/**
* Contains the model instance
*
* @var object
*/
protected $oModel = null;

/**
* @see Zend_Controller_Action::__construct()
*/
public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response,
array $invokeArgs = array()) {
parent::__construct($request, $response, $invokeArgs);

// load model, if exists
$this->getModel();
}

/**
* Loads model and returns it.
*/
protected function getModel () {
if (is_null($this->oModel)) {
// check if model exists
try {
$oModelReflection = new ReflectionClass(ucfirst($this->getRequest()->getControllerName()));

if ($oModelReflection->isInstantiable()) {
$this->oModel = $oModelReflection->newInstance();
}
} catch (Exception $e) {
/* @var $oLog Zend_Log */
$oLog = Zend_Registry::get('logger');
$oLog->log('No model available for "' . $this->getRequest()->getControllerName() . '".', Zend_Log::INFO);
}
}

return $this->oModel;
}
}

Die Datei liegt bei mir unter library/hl/controller/action.php. Um in einzelnen Controllern die Möglichkeit zu nutzen, in der Methode init() Dinge beim Initialisieren des Controller Objektes ausführen zu lassen, aber trotzdem das Model automatisch zu laden, überlade ich den Konstruktor und rufe dort die Methode getModel() auf (Zeile 17).

Mit Hilfe von Reflections prüfe ich, ob ein Model existiert. Wenn dem so ist, wird es beim ersten Aufruf von getModel() das Objekt instanziiert und in der Eigenschaft $oModel gespeichert. Ist dies erst einmal geschehen, wird bei Folgeaufrufen der Methode immer diese Instanz zurück geliefert.

Das Model muss den gleichen Namen tragen, wie der Controller. Wenn der Controller zum Beispiel UserController heißt, muss das Model User heißen. Wird die Klasse nicht gefunden, wird in dieser Version einfach ein Logeintrag der Wertigkeit ‚INFO‘ geschrieben. Dazu nutze ich die Zend_Log Klasse und erwarte eine gültige Instanz in der statischen Zend Registry unter dem Namen ‚logger‘ (Zeilen 34 und 35).

War doch gar net so schwer, oder?

Achja, ein kurzes Wort noch zum Quelltext – sorry, das die Einrückungen fehlen. Aber irgendwie verschluckt das WordPress Plugin die Spaces…

{ 1 } Trackback

  1. YABL - Yet Another BLog | 15. Juli 2011 um 10:05 | Permalink

    Zend Framework: Models automatisch (nach)laden…

    Wenn ihr auch die Models immer manuell mit folgendem Befehl in euren Controller laden müsst (oder es freiwillig tut): Zend_Loader::loadClass(‚myModel‘); Dem sei jetzt geholfen. Es gibt hier eine wunderbare Hilfe für den Autoloader, der die Models imm…

Kommentar verfassen

Dein E-Mail wird nicht veröffentlicht oder weitergegeben. Pflichtfelder sind mit * markiert.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close