ZF2 – ein Cookbook

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

Gute Nachrichten für Zend-Framework-Entwickler und alle, die es werden wollen: Zend Framework ist am 6. September in der Version 2 erschienen. Und wer schon einmal in den Code reingeschaut hat oder einen Blick in die Doku geworfen hat, wird feststellen, dass sich doch einiges seit der ersten Version geändert hat. Grund genug, in einem Cookbook zu beschreiben, wie mit ZF2 losgelegt werden kann.

Zu Schritt 1 geht es hier..

Zu Schritt 3 geht es hier.

ZF2 – ein Cookbook

Der Artikel „ZF2 – ein Cookbook“ von Jan Burkl ist erstmalig erschienen im PHP Magazin 1.2013

Businesslogik

Das Grundgerüst des Moduls Zhorty steht. Weiter geht’s mit der Businesslogik: Zu Beginn kümmern wir uns um das Formular mit zwei Feldern (Original Url, trim Url) mit einem Submit Button – und natürlich um die Datenbank, die dahinterliegt. Der Einfachheit halber nutzen wir SQLite. Die Datenbankdatei könnte z. B. in einen neuen Ordner module/Zhorty/data mit dem Namen zhorty.db angelegt werden. Eine klare Vorgabe vom ZF2 gibt es diesbezüglich nicht. In den Sourcen des fertigen Projekts [3] findet sich im Verzeichnis etc auch ein SQL-Script, mit dem die Tabelle bzw. die ganze DB-Datei angelegt werden kann. Bitte auch auf die korrekten Lese-Schreib-Rechte der Datei und des Verzeichnisses für den Webuser achten. Die erstellte Tabelle trim hat vier Felder: id, orig, trim und created.

Als Nächstes konfigurieren wir den DB-Zugriff in unserer Applikation. Prinzipiell würde das über die Modulkonfiguration funktionieren, in der Regel setzt man die Datenbank-Credentials aber applikationsweit. Dazu erstellen wir eine neue – global bzw. applikationsweit verfügbare – Datei config/autoload/db.local.php (im config-Ordner der Skeleton-App, nicht innerhalb des Zhorty-Moduls oder des Application-Moduls) mit dem Inhalt aus Listing 6.

Listing 6

 array(
         'factories' => array(
             'ZendDbAdapterAdapter' => function ($sm) {
                 return new ZendDbAdapterAdapter(array(
                     'driver' => 'PDO_SQLITE',
                     'dsn' => 'sqlite:/var/www/zhorty.dev/module/Zhorty/data/zhorty.db'
                 ));
             },
         ),
     ),
 );

Diese Datei wird automatisch als Konfiguration eingelesen (siehe config_glob_paths-Definition in config/application.config.php). Eine weitere Besonderheit ergibt sich aus der Benennung der Datei. Da sie local enthält, ist diese Datei im Git Ignore enthalten, kann also somit nicht versehentlich in Git eingecheckt werden. Damit wird das Risiko minimiert, Konfigurationsdateien für die lokale Umgebung auf das Livesystem zu deployen.

Genauso wie beim Controller machen wir auch die Datenbank dem ServiceLocator bekannt. Dieses Mal wird der Service nicht als invokable registriert, sondern als factory. Factories werden eingesetzt, wenn die Instanziierung einer Klasse etwas aufwändiger als ein new Classname() ist. Eine Möglichkeit, eine Factory zu bauen, sind, wie oben beschrieben, Code-Snippet Closures. Im Wesentlichen wird nur eine Adapter-Klasse gebaut und im Konstruktor mit den Verbindungsparametern (hier: DSN) übergeben. Wenn der ServiceLocator im Folgenden über den Key ZendDbAdapterAdapter abgefragt wird, wird die Adapter-Klasse instanziiert. Der ServiceLocator ist wiederum dafür verantwortlich, dass die Klasse auch bei mehrfachem Aufruf nicht mehrfach instanziiert wird. Der Key ZendDbAdapterAdapter ist natürlich auch hier frei gewählt. Und gerade wenn geplant wird, das Modul zu veröffentlichen, empfiehlt es sich, einen eindeutigeren Key wie z. B. ZhortyDB zu wählen. Das stellt sicher, dass auch bei Verwendung von mehrfachen DB-Verbindungen keine Konfigurationskonflikte auftreten.

Model

ZF2 hat wie auch ZF1 kein vollständiges ORM-Pattern implementiert. Für einfache Operationen auf DB-Tabellen steht die Klasse ZendDbTableGateway zur Verfügung. Wird etwas Komplexeres wie Doctrine benötigt, kann es als Modul eingebunden werden. Wir begnügen uns bei Zhorty mit dem ZendDbTableGatewayAbstractTableGateway, das als Elternklasse unseres ZhortyModelTrim in der Datei src/ZhortyModelTrim.php dient (Listing 7).

Listing 7

adapter = $adapter;
    }
    
    public function setTableName($table) {
        $this->table = $table;
    }
}

In ZF2 gibt es nicht so etwas wie einen Default-DB-Adapter. Wir sind selbst dafür verantwortlich, dem Model einen Adapter zuzuweisen. Dafür wird die Klasse setDbAdapter() implementiert. Wo dieser dem Model zugewiesen wird, erfahren wir ein paar Zeilen weiter unten. Des Weiteren gibt es noch eine Methode setTableName(), die für das Setzen des Tabellennamens gedacht ist. Genauso gut hätte der Tabellenname auch direkt als Instanzvariable gesetzt werden können. Das war es auch schon für die Basisverwendung eines Models. Jetzt benötigen wir noch eine Form, damit wir die Datenbank auch von außen (mithilfe des Models) füllen können. Dazu erstellen wir eine neue Form Klasse in src/Zhorty/Form/Trim.php (Listing 8).

Listing 8

add(array(
            'name' => 'orig_url',
            'options' => array(
                'label' => 'Original URL:',
            ),
            'attributes' => array(
                'type' => 'text'
            ),
        ));

        $this->add(array(
            'name' => 'trim_path',
            'options' => array(
                'label' => 'Trim Path:',
            ),
            'attributes' => array(
                'type' => 'text'
            ),
        ));
        
        $this->add(array(
            'name' => 'submit',
            'options' => array(
                'label' => 'Trim',
            ),
            'attributes' => array(
                'type' => 'submit'
            ),
        ));
    }
}

Wir sehen: Es gibt nur zwei Felder (und einen Submit-Button), aber keine Validatoren, keine Filter, keine Dekoratoren. Die Form-Klasse in ZF2 ist wirklich nur für das Formular an sich zuständig und somit auch viel leichtgewichtiger. Ob die übermittelten Werte valide sind, entscheidet die neue InputFilter-Klasse in Zhorty/src/Zhorty/Form/TrimFilter.php (Listing 9).

Listing 9

add(array(
            'name'       => 'orig_url',
            'required'   => true,
            'validators' => array(
                array(
                    'name' => 'uri',
                    'options' => array('allowRelative' => false)
                ),
                array(
                    'name'    => 'StringLength',
                    'options' => array(
                        'min' => 6,
                        'max' => 255,
                    ),
                ),
            ),
            'filters'   => array(
                array('name' => 'StringTrim'),
            ),
        ));

        $this->add(array(
            'name'       => 'trim_path',
            'required'   => true,
            'validators' => array(
                array(
                    'name' => 'Regex',
                    'options' => array('pattern' => '/^[a-z0-9-_]+$/'),
                ),
                array(
                    'name'    => 'StringLength',
                    'options' => array(
                        'min' => 3,
                        'max' => 30,
                    ),
                ),
            ),
            'filters'   => array(
                array('name' => 'StringTrim')
            ),
        ));
    }
}
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -