© hanss/Shutterstock.com
Alternative PHP-Router im Überblick

Neue Router braucht das Land


Die Dominanz der PHP-Frameworksilos neigt sich dem Ende zu. Auch dank der immer noch steigenden Verbreitung des Composers wird es für PHP-Entwickler immer leichter, sich aus vielen verschiedenen Bausteinen und Paketen ein eigenes Framework zusammenzustellen. Dieser Artikel bietet einen Überblick über einige PHP-Router, die als sinnvolle Alternativen bereitstehen.

Früher, in der guten alten Zeit, boten die PHP-Fullstack-Frameworks für jedes Problem in der Webentwicklung ihre eigenen Lösungen. Diese Frameworksilos waren ein geschlossenes Ökosystem, auch wenn externe Pakete wie Doctrine oder die ein oder andere Template-En­gine zusätzlich eingebunden werden konnten. Doch für elementare Aspekte wie die Modellierung von HTTP-Anfragen und -Antworten oder das Routing stellten die meisten PHP-Frameworks ihre eigenen Lösungen bereit. Das ist heute zwar immer noch so, aber die Zeiten haben sich mittlerweile geändert.

Damals war es meist etwas aufwendig, externe Pakete in ein Projekt zu integrieren. Oftmals gab es nur die Möglichkeit, das Paket herunterzuladen, zu entpacken, in einem Ordner abzulegen und ins Autoloading zu integrieren. Gab es eine neue Version, begann das Spiel von vorne. Es ist nun etwas mehr als fünf Jahre her, dass die erste Version von Composer veröffentlicht wurde [1]. Seitdem ist es kein Problem mehr, mithilfe des Composers Abhängigkeiten zu installieren und auch aktuell zu halten.

Ein weiterer Aspekt, der zur Öffnung der geschlossenen PHP-Frameworkökosysteme beitrug, war die Gründung der PHP-FIG im Jahr 2009 [2]. In der PHP Framework Interoperability Group sitzen Vertreter aller namhaften PHP-Frameworks und weiterer PHP-Open-Source-Projekte wie Composer, Drupal, Joomla!, Magento oder SugarCRM. Die Gruppe hat es sich zum Ziel gesetzt, für die PHP-Welt Standards für die Entwicklung zu etablieren. Lag der Fokus in der Anfangszeit überwiegend auf Autoloading und Coding Styles, wurden in den letzten Jahren immer öfter auch Standards in Form von Interfaces geschaffen. So gibt es mittlerweile verabschiedete Interfaces für das Logging, das Caching und die Modellierung von HTTP Messages; weitere Interfaces sind in Arbeit. Anfang 2016 beeilten sich etwa viele PHP-Frameworks, den PSR-7-Standard für die HTTP Requests und Responses in ihren Frameworks zu implementieren.

Durch diese neue Offenheit sollten PHP-Entwickler über den Tellerrand schauen und auch mal Neues ausprobieren. In diesem Artikel werfen wir einen Blick auf verschiedene Routing-Lösungen, die in den letzten Jahren als Alternativen zu den etablierten Routern der einzelnen PHP-Frameworks entstanden sind. Im Einzelnen sind das:

  • Aura.Router

  • FastRoute

  • klein.php

  • Pux

Alle Codebeispiels zum Artikel finden Sie bei GitHub [3]. Nach dem Klonen des Repositorys lassen Sie am besten Composer die Abhängigkeiten und damit die einzelnen Routerpakete installieren. Zudem sollten Sie noch Schreibrechte auf das /data/log/-Verzeichnis setzen. Danach können Sie das Projekt starten; es ist fortan auf http://0.0.0.0:8080/ im Browser abrufbar:

$ git clone https://github.com/RalfEggert/phpmagazin.router $ cd phpmagazin.router $ composer install $ sudo chmod -R 777 data/log/ $ composer serve

Verwendete Routen, Handler und Templates

Für alle vier Router werden in den Beispielen im Wesentlichen dieselben Routen, Handler und Templates verwendet, um die Vergleichbarkeit zu erhöhen. Ausnahme bilden hier nur die Handler für den Router klein. php, der leicht angepasste Handler benötigt. Alle Router implementieren ähnliche Routen, die jeweils anders benannt sind. Das Schema ist aber überall dasselbe:

  • /router/ für eine GET-Anfrage der Hauptseite

  • /router/id für eine GET-Anfrage einer Anzeigeseite für die ID

  • /router/create für eine GET-Anfrage zur Darstellung eines Formulars

  • /router/create für eine POST-Anfrage zur Verarbeitung eines Formulars

Listing 1 zeigt die Datei /handler/other_handlers.php mit einer Renderer-Funktion und einigen Handler-Funktionen, die bei den einzelnen Routen zum Einsatz kommen. Diese Handler-Funktionen sind nur zur Demonstration und enthalten keine vollständige Funktionalität. Sie werden von den einzelnen Routen verwendet, für die es zu einem Treffer gekommen ist. Für die HTML Re­sponse kommt die Zend-Framework-Komponente zend-diactoros [4] zum Einsatz, um die Vergleichbarkeit zu verbessern. Auch die Renderer-Funktion ist nur zur Demonstration gedacht.

In Listing 2 finden Sie exemplarisch das Template für die Startseite aus der Datei /tpl/home.html. Es enthält neben dem HTML Markup auch ein paar Platzhalter. Sie werden in der Renderer-Funktion entsprechend ersetzt, damit die Templates für alle Router verwendet werden können.

Listing 1

<?php use Psr\Http\Message\ServerRequestInterface; use Zend\Diactoros\Response\HtmlResponse; $renderer = function ($tpl) { $html = implode('', file($tpl)); html = str_replace('%%router_name%%', ROUTER_NAME, $html); $html = str_replace('%%router_route%%', ROUTER_ROUTE, $html); return $html; }; $homeHandler = function () use ($renderer) { $tpl = __DIR__ . '/../tpl/home.html'; $html = $renderer($tpl); return new HtmlResponse($html); }; $fileNotFoundHandler = function () use ($renderer) { $tpl = __DIR__ . '/../tpl/404.html'; $html = $renderer($tpl); return new HtmlResponse($html); }; $methodNotAllowedHandler = function () use ($renderer) { $tpl = __DIR__ . '/../tpl/405.html'; $html = $renderer($tpl); return new HtmlResponse($html); }; $showHandler = function ($request) use ($renderer) { if (is_array($request) && isset($request['request'])) { $request = $request['request']; } /** @var ServerRequestInterface $request */ $id = (int)$request->getAttribute('id'); $tpl = __DIR__ . '/../tpl/show.html'; $html = $renderer($tpl); $html = str_replace('%%id%%', $id, $html); return new HtmlResponse($html); }; $createGetHandler = function () use...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang