Ein PHP-Framework (nicht nur) für coole Kids

Laravel: Mehr Eleganz beim Programmieren
Keine Kommentare

Bei Laravel handelt es sich um ein typisches Open-Source-PHP-Framework, das dem MVC-Architekturmuster folgt. Seit der Veröffentlichung der ersten Version im Juni 2011 hat die Popularität stetig zugenommen. Spätestens mit Version 4.0, die seit Mai 2013 verfügbar ist, hat sich Laravel etabliert. Mit dieser Version ging auch die Umstellung auf eine Composer-basierte Installation und Paketverwaltung einher.

Seit jeher wird die Entwicklung von Laravel maßgeblich durch Taylor Otwell, dem Initiator und Maintaner des Projekts, vorangetrieben und geprägt. Während es gerade in der Anfangszeit noch des Öfteren selbst in Minor-Releases nicht abwärtskompatible Änderungen gab, hat sich die Situation mittlerweile deutlich entspannt. Die Dokumentation von Laravel enthält für jedes Release einen ausführlichen Upgrade-Guide mit einer Liste der relevanten Änderungen und möglichen Stolpersteine. Zudem wurde erstmalig im Juni 2015 eine Version mit Langzeitunterstützung veröffentlich. LTS-Versionen von Laravel werden für zwei Jahre nach Erscheinen mit Bugfixes und im Anschluss daran für ein weiteres Jahr mit Sicherheitsupdates versorgt.

Folglich ist es gerade jetzt ein guter Zeitpunkt, um den Einsatz von Laravel als Framework für neue oder bestehende Projekte in Betracht zu ziehen. Abgesehen von der wichtigen Langzeitunterstützung ist es vor allem auch die Akzeptanz im professionellen Umfeld, die für einen Einsatz spricht. Zu den bekannten Anwendern von Laravel zählen unter anderem das Schnäppchenportal mydealz und der Onlineshop AboutYou.

MVC 101

Laravel bietet als Full-Stack Framework alle nötigen Funktionen, um professionelle Webapplikationen zu entwickeln. Mittels Composer ist ein neues Projekt auf Basis von Laravel schnell mit der folgenden Zeile eingerichtet: composer create-project –prefer-dist laravel/laravel mein-shop.

In den grundlegenden Funktionen weist Laravel viele Parallelen mit anderen Frameworks wie Symfony auf. So werden die einzelnen Seiten respektive http Endpoints einer Webanwendung dem MVC-Entwurfsmuster entsprechend in Controller-Klassen zusammengefasst. Die URLs für den Zugriff darauf werden als so genannte Routes definiert. Hierbei ist man nicht eingeschränkt und kann das URL-Schema frei gestalten. Verwendete Platzhalter können optional auf einen regulären Ausdruck geprüft werden oder dazu dienen, ein benötigtes Model automatisch aus der Datenbank zu laden und im Controller bereitzustellen:

// routes.php
Route::get(“orders/{order}/invoice.pdf”, “OrdersController@getInvoicePdf”);

// OrdersController.php
public function getInvoicePdf(Order $order) {
return response()->download($order->getInvoicePath(), “invoice.pdf“);
// Das Model mit der im Platzhalter genutzten ID ist direkt in der Controller-Methode verfügbar
}

Ebenfalls lassen sich Routes speziell für einzelne oder alle Subdomains definieren. Gerade für SaaS-Anwendungen, bei denen jeder Mandant eine eigene Subdomain erhält, ist das durchaus praktisch. Das von einem Platzhalter erfasste Segment der Subdomain kann dabei als Parameter an die Controller-Methoden weitergereicht und dort verwendet werden.

Laravel unterstützt die Datenbanken MySQL, PostgreSQL, SQLite, SQL Server und den Key-Value-Store Redis. Für die Arbeit mit einer Datenbank bietet Laravel neben einem Query Builder, der das Erstellen sicherer, vor SQL Injections geschützter SQL-Abfragen vereinfacht, auch ein ORM namens Eloquent. Eloquent nutzt, anders als beispielsweise Doctrine, kein Data-Mapper-Pattern, sondern das Active-Record-Pattern. Während so ein unkomplizierter Einstieg in die Entwicklung möglich ist, sollte man sich bewusst sein, dass Active Record zumindest in Hinsicht auf die SOLID-Prinzipien ein Antipattern ist. Es werden verschiedene Zuständigkeiten – vor allem Domain-/Business-Logik und Persistenz – in einer Klasse vermischt, was nicht selten zu so genannten Gottobjekten führt.

International PHP Conference

WordPress for Modern Developers

by Samuel Lev (Determined Development Pty Ltd)

JavaScript Days 2020

Architektur mit JavaScript

mit Golo Roden (the native web)


Der Einsatz von Eloquent ist dementsprechend eine Geschmacksfrage und kann gerade bei komplexen Projekten problematisch sein. Während Laravel standardmäßig auf die Verwendung von Eloquent angepasst ist, spricht aber nichts dagegen, stattdessen ein anderes ORM einzusetzen oder die Datenbankabfragen direkt mittels Query Builder zu erstellen und in Repository-Klassen zu kapseln. Abseits vom reinen Datenbankzugriff bietet Laravel mit den Migration-Klassen eine leicht zugängliche Funktion zum Erstellen und Modifizieren des Datenbankschemas. Gerade für das automatisierte Testen und während der Entwicklung werden realistische Testdaten benötigt. Damit diese nicht jedes Mal von Hand angelegt oder umständlich in Form von SQL Dumps weitergegeben werden müssen, lässt sich die Generierung von Testdaten in separaten Seeder-Klassen abbilden. Hierbei stehen verschiedene nützliche Hilfsfunktionen bereit.

Für die Ausgabe von HTML-Code bringt Laravel eine eigene Templatesprache mit. Die Ähnlichkeiten von Blade, so der Name, und dem Template-System Razor aus dem ASP.NET-Framework sind nicht zufällig. Die Idee zu Laravel entstand, als Taylor Otwell kein mit ASP.NET vergleichbares Framework für PHP finden konnte. Im Kern handelt es sich bei Blade-Templates um gewöhnliche HTML-Dokumente, die durch spezielle Tags um Logik erweitert werden. Von ihnen bietet Laravel eine ganze Reihe, die den Entwickleralltag komfortabler gestalten:

@forelse($orders as $order)
  <li>{{ $order->id }}: {{ $order->total }} €</li>
@empty
  <p>Keine Bestellungen vorhanden.</p>
@endforelse
// Nützlich: Das Handling einer leeren Ergebnisliste wird durch Blade vereinfacht

Ebenfalls Bestandteil von Laravel ist ein Frontend-Grundgerüst auf Basis von Vue.js und Bootstrap. Wem Vue.js nicht zusagt, der kann die Vorlage mittels Artisan auf React umstellen. Artisan ist das Laravel-eigene Kommandozeilenwerkzeug, mit dem viele Aufgaben wie z. B. Codegenerierung erledigt werden können. Um die Konfiguration von webpack zu vereinfachen, wird das npm-Paket Laravel Mix mitgeliefert. Standardaufgaben wie das Kompilieren und Minifizieren von Assets sind so schnell eingerichtet und leicht anpassbar.

Für reine API-Projekte, z. B. im Zusammenspiel mit einer Single Page Application, wird eine JWT-basierte Authentifizierung angeboten. Diese ist auch bereits im Frontend-Grundgerüst vorkonfiguriert. Neben der vollständigen Laravel-Installation steht mit Laravel Lumen auch eine Art „Laravel light“ für die Entwicklung von APIs bereit. Zur Steigerung der Performance wurden hier einige für APIs weniger relevante Funktionen entfernt. So fehlt unter anderem das gesamte Session-Handling, wodurch eine Authentifizierung immer mittels API Key oder Token erfolgen muss. Sollten sich die Anforderungen eines Projekts ändern, ist ein Upgrade auf die vollständige Laravel-Version jederzeit möglich.

Warum Laravel?

Zu Recht stellt sich nun vermutlich die Frage, was Laravel konkret von der Vielzahl an konkurrierenden PHP Frameworks abgrenzt und zu einer guten Wahl macht. Da die bisher genannten Funktionen so oder in ähnlicher Form in fast jedem Framework enthalten sind, werde ich im Folgenden auf eine Auswahl von Features eingehen, die aus meiner Sicht herausstechen.

Bereits die Laravel zugrunde liegende Softwarearchitektur ist sehr elegant. So wird durchgängig auf Dependency Injection als Entwurfsmuster gesetzt, um die Wart- und Testbarkeit der Anwendungen zu erhöhen. Dreh- und Angelpunkt ist hierbei der Service-Container, der für die Auflösung und Bereitstellung von Abhängigkeiten zuständig ist. Dadurch ist es nicht nötig, auf globale Objekte oder statische Klassen zurückzugreifen. Statt einer manueller Instanziierung der Abhängigkeiten im Code werden diese einfach vom Service-Container angefordert. Das geschieht entweder explizit durch den Aufruf einer Hilfsfunktion oder impliziert innerhalb von Objekten, die ebenfalls vom Service-Container bereitgestellt werden. Hierzu zählen auch alle Controller-Klassen. Enthält die Parameterliste eines Objektkonstruktors eine typisierte Abhängigkeit, wird der Service-Container versuchen, sie im Konstruktor zu injizieren:

CartController extends Controller {
  public function __construct(CartService $cartService) {
    $this->cartService = $cartService;
  }
}
// die Abhängigkeit zum CartService wird automatisch aufgelöst, da der Cart Controller ebenfalls vom Service Container instanziert wird

Standardmäßig erfolgt die Instanziierung schlicht mittels new Dependency();. Für komplexe Objekte mit eigenen Abhängigkeiten bieten sich Service-Provider an. Hierbei handelt es sich um gesonderte Klassen, die definieren, wie bestimmte Objekte vom Service-Container zu erzeugen sind.

Praktisch ist zudem, dass nicht nur reguläre Klassen, sondern auch abstrakte Klassen oder Interfaces als Abhängigkeiten angegeben werden können. Um sie auflösen zu können, ist die Registrierung einer konkreten Implementierung im Service-Provider notwendig. Möchte man bestimmte Objekte nicht stets neu erzeugen lassen, können sie auch als Singleton definiert werden. Beim ersten Zugriff auf diese Abhängigkeit wird sie dann vom Service-Container erzeugt und bei jeder folgenden Anfrage stets diese Instanz wiederverwendet.

Um Funktionalität zu kapseln, die mehr als einen HTTP-Endpoint betrifft und eigentlich nicht Teil der jeweiligen Logik ist, kann eine so genannte Middleware erstellt werden. Dabei handelt es sich um eine Klasse oder Funktion, die die eigentliche Controller-Methode umschließt und den Request oder die Response modifizieren kann. Es lassen sich mehrere Middlewares in Reihe schalten, sodass man bei einem API beispielsweise die Authentifizierung oder ein etwaiges Throttling in separaten Klassen implementieren kann. In Laravel selbst ist unter anderem das Session-Handling und die CSRF-Token-Validierung als Middleware umgesetzt.

Wie bereits erwähnt, liefert Laravel ein eigenes CLI-Tool namens Artisan mit. Hiermit lassen sich nicht nur Framework-spezifische Aufgaben wie das Generieren von Controller- oder Model-Klassen durchführen, sondern es können auch eigene Funktionen (Commands) realisiert werden. Das sind typischerweise jene Funktionen, die man periodisch als Cronjob ausführen lassen möchte, um Back-ups zu erstellen, Zahlungserinnerungen zu versenden oder Daten mit Drittsystemen zu synchronisieren. Zwar lassen sich die eigenen Artisan Commands ganz normal als Cronjob konfigurieren, doch einfacher ist es, den Task Scheduler zu nutzen. So lässt sich das Intervall mit einer leichtverständlichen Syntax definieren, und es ist lediglich nötig, den Task Scheduler selbst als Cronjob zu hinterlegen:

$scheduler->command(“meinshop:send-payment-reminder”)->daily();
// Das eigene Artisan Command wird täglich ausgeführt

In vielen Anwendungen wird eine Dateiuploadfunktion benötigt, und sei es nur, um dem Nutzer das Hochladen eines eigenen Profilbilds zu ermöglichen. Aber auch sonst fallen oft Dateien an, die irgendwo gespeichert werden müssen. Um das zu vereinfachen, bietet Laravel eine separate Abstraktionsschicht, sodass es aus Entwicklersicht kaum einen Unterschied macht, ob die Daten auf der lokalen Festplatte, einem (S)FTP-Server oder in einem AWS S3 Bucket abgelegt werden. Die Funktionen zum Speichern, Laden oder Löschen von Dateien stehen hierbei in Form eines einheitlichen API zur Verfügung. Wie für Laravel üblich, besteht auch hier die Möglichkeit, weitere Services anzubinden. In der Dokumentation ist das am Beispiel von Dropbox als zusätzlichem Speicherort erläutert. Sobald die eigene Anwendung eine gewisse Nutzeranzahl erreicht, wird das Thema Performance immer bedeutsamer. Eine wirkungsvolle Optimierung ist klassischerweise das Caching, damit die Anzahl der nötigen Datenbankabfragen reduziert wird oder Daten, die aus dem API eines Drittanbieters bezogen werden, nicht in jedem Request erneut abgerufen werden müssen. Von Haus aus unterstützt Laravel Datenbanken, Redis, Memcached oder das Dateisystem als Backend für das Cache-System.

Ein weiterer Ansatz ist das Auslagern nachrangiger oder zeitintensiver Vorgänge, wie z. B. das Versenden von Bestätigungs-E-Mails, aus der eigentlichen Controller-Logik. Diese Aufgaben werden in einer Queue abgelegt und von einem oder mehreren separaten Hintergrundprozess(en) abgearbeitet. Dadurch wird die Antwortzeit für den Endnutzer merklich reduziert, da die Antwort viel schneller generiert und vom Server an den Browser gesendet werden kann. Das Queue-System unterstützt nicht nur verschiedene Backends, sondern ist auch sonst sehr flexibel. Aufgaben können sowohl direkt ausgeführt als auch für einen späteren Zeitpunkt vorgeplant oder mit unterschiedlicher Priorität abgearbeitet werden, schließlich ist nicht jede Aufgabe gleich relevant. Während die Bestellbestätigung oder die „Passwort vergessen“-E-Mail am besten direkt im Postfach des Nutzers landen soll, darf der tägliche Report für das Team vielleicht auch mal etwas später generiert und versendet werden. Selbst wenn aktuell kein Einsatz von Laravel geplant ist, kann ich jedem nur empfehlen, schon alleine wegen dieses Features einen Blick in die umfangreiche und erstklassige Laravel-Dokumentation zu werfen.

Natürlich kommt auch das Thema automatisiertes Testing nicht zu kurz. Neben den üblichen Verdächtigen wie Unit-Tests mittels PHPUnit unterstützt Laravel auch browserbasierte Tests mit Laravel Dusk. Gerade in Zeiten, in denen immer mehr Logik ins Frontend verlagert wird, ist es eigentlich unumgänglich, direkt in einem Browser zu testen. Diese Tests lassen sich wie gewohnt in PHP schreiben und können mit ChromeDriver oder einem Selenium-Server ausgeführt werden.

Für Neueinsteiger ist es verwunderlich, dass in Codebeispielen zu Laravel oft vermeintlich statische Klassen wie Request, Session oder Cache genutzt werden. Tatsächlich handelt es sich hierbei aber nicht um statische Klassen im eigentlichen Sinne, sondern um von Laravel als Facades bezeichnete Wrapper, die Objekte im Service-Container referenzieren. Es ist ohne Weiteres möglich, einzelne Funktionen dieser Facades für Unit-Tests zu mocken. Auch erhält man dank Dependency Injection beispielsweise einfach Zugriff auf die Instanz des aktuellen Requests, indem man die Request-Klasse in die Parameterliste aufnimmt. So können alle bisherigen Aufrufe auf der Request Facade durch direkte Aufrufe auf dem eigentlichen Request-Objekt ersetzt werden.

Darf es etwas mehr sein?

Ohne ein Feature im eigentlichen Sinne zu sein, dürfte einer der größten Pluspunkte das um Laravel herum entstandene Ökosystem sein. Während Laravel selbst schon einen beachtlichen Funktionsumfang liefert, erhält man hier nochmals eine Fülle an weiteren Features oder Hilfestellungen. Für die Serverkonfiguration und das Deployment gibt es Laravel Forge und Envoyer. Das lästige Verwalten von Servern gehört damit der Vergangenheit an. Grundlegendes wie automatische Sicherheitsupdates des Betriebssystems und der Software, das Einrichten von SSL-Zertifikaten oder ein Git-basierter Zero-Downtime-Deployment-Prozess sind hier bereits sehr gut gelöst, sodass man sich voll und ganz auf das eigentliche Projekt und den eigenen Code fokussieren kann.

Für die lokale Entwicklung gibt es mit Laravel Homestead eine fertige Vagrant-Box, die nichts vermissen lässt und somit den direkten Einstieg in die Entwicklung ermöglicht. Für Mac-Nutzer gibt es mit Laravel Valet eine Alternative, die auf lokale Komponenten statt eine virtualisierte Linux-Maschine setzt. Das ist nicht nur ressourcenschonender, sondern für viele Projekte auch vollkommen ausreichend. Hinzu kommt, dass es für viele API-Clients und Pakete von Drittanbietern bereits speziell auf Laravel zugeschnittene Versionen gibt, die ihre Abhängigkeiten beispielsweise direkt im Service-Container registrieren oder ihre Funktionen in Form von Middleware bereitstellen.

SaaS-Projekte können vom Einsatz von Laravel Spark profitieren. Das kostenpflichte Paket beinhaltet typische Funktionen, die in einer solchen Anwendung benötigt werden. Dazu zählen eine Team- und Rechteverwaltung oder die Abwicklung wiederkehrender Kreditkartenzahlungen mit Stripe. Wer neben einem schönen Endnutzer-Frontend auch Wert auf eine moderne und ansehnliche Administrationsoberfläche legt, kann einen Blick auf das ebenfalls kostenpflichtige Laravel Nova werfen. Beide Pakete stammen auf der Feder des Laravel-Schöpfers Taylor Otwell und bieten somit natürlich eine perfekte Integration mit dem Framework.

Fazit

Wie so oft in der Softwareentwicklung, lässt sich auch die Frage, ob man Laravel einsetzen oder gar bestehende Projekte hin zu Laravel migrieren sollte, mit einem klaren „it depends“ beantworten. Eine pauschale Antwort ist nicht möglich, und es kommt immer auf den konkreten Projektkontext an. Für neue Projekte, bei denen auch die benötigte Einarbeitungszeit keine Deadline sprengt, sollte man sich Laravel unbedingt anschauen. Es zählt nicht ohne Grund zu den populärsten Frameworks und bietet rein aus technischer Sicht eine absolut solide Grundlage für kleine und große Projekte. Gerade die LTS-Releases sprechen für einen Einsatz in langfristig ausgelegten Projekten.

Da im Rahmen eines Artikels nicht vollumfänglich auf jede Funktion eingegangen werden kann, stellt die offizielle Dokumentation eine erste Anlaufstelle für tiefergehende Informationen dar. Sie ist gut gegliedert, leicht verständlich und vor allem aktuell. Persönlich kann ich nur feststellen, dass es nicht ausschließlich die vielen Features und Lösungen aus dem Laravel-Ökosystem sind, die Laravel nach wie vor zum Framework meiner Wahl machen. Vielmehr sind es die unzähligen kleinen Details, die mich immer wieder denken lassen „Cool, da hat sich jemand wirklich Gedanken gemacht und eine smarte Lösung gefunden.“, was letztlich dazu führt, dass das Entwickeln mit Laravel einfach Freude bereitet.

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Kiosk ist das PHP Magazin weiterhin im Print-Abonnement erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -