Entries Tagged as 'Frameworks'

Zend Framework Hostname-Routen und Pfad-Routen in der application.ini verketten

Wie man Pfad-Routen in der application.ini definiert ist recht “gut” dokumentiert in der Dokumentation des Zend-Controllers (Router) – wobei gut auch dort nicht ganz richtig ist. Irgendwie wirkt die Dokumentation des Frameworks auf mich immer ein wenig wie eine Snippet-Sammlung – sprich: Man wird in den Kontext reingeworfen und versucht rudernd nicht im Meer des Missverstehens unterzugehen.

Wie dem auch sei. In der Dokumentation findet man “prima” beschrieben, wie man das ganze in der Bootstrap.php z.B. löst:

// Erstellung zweier Routen
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(...);
$pathRoute     = new Zend_Controller_Router_Route(...);

// Erster Weg, mit Verkettung über die Chain Route
$chainedRoute = new Zend_Controller_Router_Route_Chain();
$chainedRoute->chain($hostnameRoute)
             ->chain($pathRoute);

// Zweiter Weg, direkt verketten
$chainedRoute = $hostnameRoute->chain($pathRoute);

Ich würde das ganze ja noch um folgendes ergänzen: Zum einen sollte man das ganze in eine protected _initRouter()-Methode packen und zum anderen folgendes davor bzw. danach hinzufügen – nur um den Kontext abzurunden versteht sich :) .

$this->router = $this->frontController->getRouter();
$this->router->removeDefaultRoutes();

[... Code von oben ...]

$this->router->addRoute('verySpecialNameOfRoute', $chainedRoute);

Ja ich weiß kann man alles auch noch viel besser zusammenfassen, aber so kann man es nu besser erkennen. Darauf wollte ich aber eigentlich ja nicht hinaus wie ich schon weiter oben schrob geht es mir mehr um die Implementierung bzw. Definition der Verkettung einer Hostname- mit einer Pfad-Route.
Nun alle Routen in der Bootstrap.php zu definieren ist zwar ohne weiteres möglich – ich persönlich halte allerdings nicht sehr viel davon. Zumal eine ordentlich kommentierte und genutzte .ini-Datei für die meisten pflegbar ist und nicht lediglich für solche, die PHP verstehen.

Wie wir das ganze über die Zend_config mit der Definition eines Arrays lösen finden wir auch halbwegs brauchbar in der Dokumentation des Controllers bzw. des Routers der Teil des selbigen ist. Gut es wird hier kein Beispiel für den Zend_Controller_Router_Route_Hostname in Zusammenhang mit der Verkettung des selbigen mit einer Pfad-Route (Zend_Controller_Router_Route z.B.) gegeben aber immerhin werden hier zwei Routen verkettet und man kann das ja dann ohne weiteres ableiten.

$config = new Zend_Config(array(
    'chainName' => array(
        'type'   => 'Zend_Controller_Router_Route_Static',
        'route'  => 'foo',
        'chains' => array(
            'subRouteName' => array(
                'type'     => 'Zend_Controller_Router_Route_Static',
                'route'    => 'bar',
                'defaults' => array(
                    'module'      => 'module',
                     'controller' => 'controller',
                     'action'     => 'action'
                )
            )
        )
    )
));

Wie schon erwähnt, es sind zwei Pfad-Routen, die da verknüpft werden, aber es wird bestimmt fast jeder in der Lage sein die Zend_Controller_Router_Route_Static in eine für den Fall benötigte Zend_Controller_Router_Route_Hostname umzuwandeln (Tipp: Daran denken die “route” auf den richtigen Wert zu setzen ;) ). Gut! Nun aber zur .ini: Das Zend Framework bzw. die Dokumentation des Frameworks bietet uns folgendes für die .ini an:

routes.archive.route = "archive/:year/*"
routes.archive.defaults.controller = archive
routes.archive.defaults.action = show
routes.archive.defaults.year = 2000
routes.archive.reqs.year = "\d+"

routes.news.type = "Zend_Controller_Router_Route_Static"
routes.news.route = "news"
routes.news.defaults.controller = "news"
routes.news.defaults.action = "list"

routes.archive.type = "Zend_Controller_Router_Route_Regex"
routes.archive.route = "archive/(\d+)"
routes.archive.defaults.controller = "archive"
routes.archive.defaults.action = "show"
routes.archive.map.1 = "year"
; OR: routes.archive.map.year = 1

und:

$config = new Zend_Config_Ini('/path/to/config.ini', 'production');
$router = new Zend_Controller_Router_Rewrite();
$router->addConfig($config, 'routes');

Öhm?! Ja… Eben ging es noch um die Verkettung von Routen und jetzt werden hier drei der Standards definiert, aber keinerlei Hinweis auf eine Verkettung?! Komplett aus dem Kontext des vorhergegangen heraus. Prima. Um es kurz zu machen: Man kann das ganze von der Definition mir Hilfe des Arrays ableiten.

# router settings - start
[routes]
# default routes regular website - start
# hostname route
routes.defaultHost.type = "Zend_Controller_Router_Route_Hostname"
routes.defaultHost.route = "sub.domain.tld"

# longterm
routes.defaultHost.chains.longterm.type = "Zend_Controller_Router_Route"
routes.defaultHost.chains.longterm.route = ":city/long-term-forecast"
routes.defaultHost.chains.longterm.defaults.controller = "index"
routes.defaultHost.chains.longterm.defaults.action = "longtermForecast"
routes.defaultHost.chains.longterm.defaults.city = null

# contact
routes.defaultHost.chains.contact.type = "Zend_Controller_Router_Route"
routes.defaultHost.chains.contact.route = "contact/*"
routes.defaultHost.chains.contact.defaults.controller = "contact"
routes.defaultHost.chains.contact.defaults.action = "index"
# default routes regular website - end

# default routes mobile website - start
# hostname route
routes.mobileHost.type = "Zend_Controller_Router_Route_Hostname"
routes.mobileHost.route = "m.domain.tld"

routes.mobileHost.chains.longterm.type = "Zend_Controller_Router_Route"
routes.mobileHost.chains.longterm.route = ":city/long-term-forecast"
routes.mobileHost.chains.longterm.defaults.controller = "mobile"
routes.mobileHost.chains.longterm.defaults.action = "longtermForecast"
routes.mobileHost.chains.longterm.defaults.city = null

Das ganze ist nur ein Auszug aus der Definition die ich für eines unserer Projekte vorgenommen habe. Funktioniert aber ganz wunderbar und lässt sich so vor allem prima warten/pflegen.

Nur damit keine Missverständnisse aufkommen: Ich mag das Zend Framework und ich finde die meisten Sachen wirklich gut gelöst – schreibe ja auch was dazu (Beispielsweise zu hybriden Models mit/trotz Zend_Db_Table_Abstract) – nur halt die Doku ist ein wenig für den A***h ;)

Zend Framework hybrides Model mit/trotz Zend_Db_table_Abstract

Nachdem ich da ein wenig rumprobieren musste und echt froh bin, dass es nun tut muss ich es auch mal ins Netz hinaustragen.
Wenn man mit Zend_Db_Table_Abstract – was ja standardmäßig an eine Tabelle gebunden ist – auf eine andere – via JOIN z.B. oder auch einfach nur so – zugreifen möchte haut einem der Integritätscheck dazwischen und versorgt einen mit dieser netten Meldung:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

Und das obwohl der SQL vollkommen in Ordnung ist, wenn man sich diesen via …

	echo $select->__tostring();

… ausgeben lässt und direkt ausführt- sprich er liefert das gewünschte Ergebnis. Das ganze verhindern kann man indem man den Intergritätscheck abschaltet.

    $select = $this->select()->setIntegrityCheck(false);
    $select->from('weather_base', 'weather_base.url')
        ->where('weather_base.id_weather_base = ?', 2);		

    // echo $select->__tostring();

    $result = $this->fetchRow($select);

Ich persönlich finde die Meldung – besonders den Teil mit You have an error in your SQL syntax etwas irreführend. Außerdem habe ich in meinem SQL eben nicht auf eine weitere Tablelle zugegriffen, sondern lediglich die ausgewählten Felder eingeschränkt.

Fliks Coding-Camp in Eckernförde

So heute sind wir also in Eckernförde eingefallen. Morgen geht’s richtig los. Netz funktioniert einwandfrei und ich freue mich auf morgen. Themen werden Frameworks unter PHP und Python sein. Optimierung von Entwicklungszeiten, Wartbarkeit, Performance und möglichst flexibles Entwickeln werden wichtige Kriterien sein. Aber dazu später mehr.

Nach unserer Ankunft – A1 fahren ist kein Spaß: Eine Baustelle nach der anderen (Autofahrt: BO-PC 562 und BO-PC 564)- haben wir uns erstmal häuslich eingerichtet, haben uns leiblich versorgt und etwas entspannt. Nu gehts ab ins Bett sonst wird das morgen nix :)