ZF2 – ein Cookbook

In 3 Schritten einen URL-Shortener mit dem neuen Zend Framework 2 bauen [Schritt 2]
Kommentare

Eine Entity könnte als Container für Daten bezeichnet werden und ist im ersten Schritt eigentlich nur eine Sammlung von (public) Klassen-Membern, die den Formularfeldern und in der Regel auch den Spaltennamen

Eine Entity könnte als Container für Daten bezeichnet werden und ist im ersten Schritt eigentlich nur eine Sammlung von (public) Klassen-Membern, die den Formularfeldern und in der Regel auch den Spaltennamen in der korrespondierenden DB-Tabelle entsprechen. Zusätzlich gibt es noch für jede dieser Variablen einen Setter und einen Getter. Die wollen wir mit einem so genannten „Hydrator“ nutzen. Ein Hydrator – frei übersetzt ein „Benetzer“ – ist ein Layer zwischen Rohdaten und Datencontainer. Die Rohdaten

werden in einem Array dem Hydrator übergeben. Abhängig vom Typ des Hydrators weiß er, wie die Daten in der Entity gespeichert werden. Um die Getter und Setter der Entitys einsetzen zu können, realisieren wir einen ClassMethod-Hydrator beim Aufsetzen der Form im ServiceLocator. Der bisherige Inhalt der Methode Module::getServiceConfig() in der Module.php kann mit folgendem Code überschrieben werden (Listing 14).

Listing 14

return array(
    'invokables' => array(
        'ZhortyEntityTrim' => 'ZhortyEntityTrim',
        'ZhortyEntityTrimHydrator' => 'ZendStdlibHydratorClassMethods',
    ),
    'factories' => array(
            'ZhortyFormTrim' => function($sm) {
            $form = new FormTrim();
            $form->setInputFilter(new FormTrimFilter());
            $form->setHydrator($sm->get('ZhortyEntityTrimHydrator'));
            $form->bind($sm->get('ZhortyEntityTrim'));
            return $form;
        },
    ),
);

Wir holen aus dem ServiceLocator den entsprechenden Hydrator (der selbst über ein invokables im ServiceLocator registriert wurde) und stecken ihn in die Form hinein. Die zweite Zeile bindet unsere Entity an die Form. Dieses geänderte Form-Objekt können wir jetzt sehr schön im Controller nutzen (Listing 15).

Listing 15

public function indexAction()
{
    $sm = $this->getServiceLocator();
    $form = $sm->get('ZhortyFormTrim');

    if ($this->request->isPost()) {
        $form->setData($this->request->getPost());
        if ($form->isValid()) {
            $model = $sm->get('ZhortyModelTrim');
           $model->save($form->getData());
           
            return $this->redirect()->toRoute('zhorty-trim');
        }      
    }
        
    return new ViewModel(array('form' => $form));
}

Die Daten werden über den POST-Request in die Form gesetzt, validiert, gefiltert und als Entity herausgeholt. Aufgrund des Hydrators muss weiter nichts getan werden. Die Entity schließlich wird dem Model in der save()-Methode des Models zum Speichern übergeben. Nach erfolgreichem Einfügen redirecten wir derzeit auf die aufrufende Seite selbst, da wir noch nichts anderes haben. Leider gibt es im Moment noch keine Model::save()-Methode. Prinzipiell existiert zwar eine insert()-Methode. Die jedoch akzeptiert nur ein Array, aber keine Entity. Deshalb bauen wir uns im Model eine eigene save()-Methode und eine weitere Kleinigkeit: eine setEntityHdyrator()-Methode. Wir werden den vorher definierten Hydrator für das Speichern umgekehrt als bisher benutzen, also die Daten von der Entity zurück in ein Array wandeln (Listing 16).

Listing 16

public function setEntityHydrator(Hydrator $entityHydrator)
{
    $this->entityHydrator = $entityHydrator;
}
    
public function save(ZhortyEntityTrim $entity) {
    $this->entity = $entity;
    $set = $this->entityHydrator->extract($entity);
    return parent::insert($set);
}

Die privaten Klassen-Members $entityHydrator und $entity müssen ebenfalls gesetzt werden. Außerdem ist es notwendig, folgendes use-Statement hinzuzufügen, damit die Klasse bzw. das Interface Hydrator gefunden werden kann:

use ZendStdlibHydratorHydratorInterface as Hydrator;

Das Array aus der extract()-Methode des Hydrators kann direkt in der parent::insert() benutzt werden. Das Model muss schlussendlich noch dem ServiceLocator als Factory in der Module.php bekannt gemacht werden. Dazu muss folgender Code in der Module::getServiceConfig() als weiterer Eintrag des Arrays mit dem Key factories hinzugefügt werden:

'ZhortyModelTrim' =>  function($sm) {
        $dbAdapter = $sm->get('ZendDbAdapterAdapter');
    $table = new ModelTrim($dbAdapter);
    $table->setTableName('trim');
    $table->setDbAdapter($dbAdapter);
    $table->setEntityHydrator($sm->get('ZhortyEntityTrimHydrator'));
    return $table;
},

Zeit zum Testen. Fehlerhafte Angaben sollten bei Abschicken des Formulars erkannt und angezeigt werden, erfolgreiche Submits direkt in der Datenbank landen.

Im November 2006 startete Jan Burkl als Training & System Engineer bei Zend Technologies in Stuttgart. Heute berät der studierte Informatiker als Senior Solution Consultant für Zend-Geschäftskunden in PHP-Softwareprojekten und ist verantwortlich für deutschsprachige Webinare und Konferenzbeiträge von Zend. Sie möchten auch eine Einladung zu phpcloud.com? Schreiben Sie eine E-Mail an jan@zend.com.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -