https://d226lax1qjow5r.cloudfront.net/blog/blogposts/laravel-9-strap-in/laravel-9.png

Laravel 9: Anschnallen!

Zuletzt aktualisiert am February 23, 2022

Lesedauer: 6 Minuten

Seit einem Jahr wird daran gearbeitet, und am 8. Februar wurde es endlich ausgeliefert: Laravel 9 ist da! In diesem Artikel werden wir ein paar neue Funktionen durchgehen, aber anstatt einer "Liste von Dingen", werde ich einige Kommentare und zusätzlichen Kontext zu den Änderungen, die mein Auge gefangen haben, bieten.

Der große Wurf

Es gibt keine großen architektonischen Änderungen oder Änderungen, die die Alarmglocken für die Rückwärtskompatibilität läuten lassen (abgesehen davon ist dies eine Hauptversion und enthält daher Änderungen, die im Einklang mit semver). Es gibt jedoch einige große Änderungen außerhalb des Codes. Lassen Sie uns diese durchgehen:

Freigabe-Zyklus

Eine der größten Änderungen innerhalb von Laravel war vor kurzem die Ankündigung von Taylor Otwell, dass sie zu einem jährlichen Release-Zyklus übergehen. Dies macht Sinn, da es dem Kernteam mehr Zeit gibt, um Aktualisierungen der Abhängigkeiten innerhalb des Symfony-Ökosystems oder der von der Community erstellten Abhängigkeiten zu prüfen. Apropos Symfony:

Symfony Mailer

Symfony Mailer hat Swift Mailer abgelöst. Zum Thema Symfony hatte ich ein sehr interessantes Gespräch mit den Leuten von SensioLabs während der PHPUK zum Thema der Interaktion von Laravel und Symfony miteinander. Einige Entwickler mögen sich als Markenbotschafter des einen oder anderen sehen und denken, dass es die Norm ist, "Partei zu ergreifen", aber wie man an den artisan cliSymfony Mailer und anderen Teilen von Laravel ist es klar, dass die beiden Frameworks weit mehr zusammenarbeiten, als die Leute, die versuchen, sich abzugrenzen, vielleicht wissen. Es lohnt sich daran zu erinnern, dass beide Fabien Potencier und Taylor Otwell beide Code zu den Organisationen des jeweils anderen beitragen, und dass das PHP-Ökosystem als Ganzes dadurch eine moderne Relevanz und Richtung erhält.

PHP8

Ich erinnere mich, dass ich Jenny Wong von Human Made einen Vortrag über WordPress-Sicherheit hielt und wie die Einführung von Jetpack ein wichtiges Werkzeug für das WordPress-Ökosystem war, auch wenn die Akzeptanz sehr gering war. Eine der größten Schwachstellen von PHP ist die mangelnde Bereitschaft der Entwickler, ihre PHP-Versionen zu aktualisieren. Über 50 % der WordPress-Szene nutzte zu diesem Zeitpunkt Software mit PHP-Versionen, die nicht einmal unterstützt wurden.

Es ist also ein enormer Fortschritt zu sehen, dass Laravel die erforderlichen PHP-Versionen im Einklang mit dem Kern-PHP-Lebenszyklus anhebt. Es gibt Zugang zu einer ganzen Reihe neuer API-Funktionen, aber noch wichtiger ist, dass das Erzwingen einer Mindestversion von PHP8 bedeutet, dass Sie den Just-In-Time (JIT)-Laufzeitcompiler erhalten, und somit profitiert Laravel von einer erheblichen Leistungssteigerung.

Mit einer neuen Mindestanforderung könnten Sie bei Ihrem Server-Stack in die Klemme geraten. Wenn es ein ernsthaftes Problem ist, weil Sie bestehende Anwendungen einsetzen, empfehle ich dringend die Verwendung von Laravel-Verschiebung um Ihre Projekte automatisch zu migrieren.

Flysystem

Eines der besten Features, die ich als Entwickler bei der Einführung in Laravel erlebt habe, war, wie die Storage Fassade um das Flysystem von Frank De Jong gewickelt ist. Die Möglichkeit, einen Dateisystemtreiber von einem lokalen zu einem AWS S3-Bucket zu wechseln, indem man die Treiber umschaltet:

Storage::disk('local')->put('something.jpg', 'Images'); Storage::disk('s3')->put('something.jpg', 'Images');

Flysystem 3.0.0 wurde am 14. Januar veröffentlicht und enthält Versionssprünge in Übereinstimmung mit Laravels Mindestanforderung für PHP8 (speziell für Flysystem 8.0.2) und API-Verbesserungen rund um die Verzeichnisnavigation wie FilesystemReader::directoryExists('Storage\Images')

Laravel 9 verwendet jetzt Flysystem 3.

Der Kleinkram

Dabei handelt es sich um kleinere Verbesserungen und Ergänzungen, die sich jedoch zu einem großartigen Paket an neuen Funktionen summieren.

Fahrdienstleiter-Gruppierung

Ich gebe zu, dass ich sehr eigen bin, wenn es um die Organisation von Routen in Web Applications geht. Ich denke, das kommt von der Erfahrung, riesige Routendateien mit mehr als tausend Einträgen zu sehen, die wenig Struktur haben, wie sie angeordnet sind. Die Art und Weise, wie ich das Routing angehe, ist die Verwendung von Verzeichnisstrukturen für einzelne Controller, die vom Routes Service Provider geladen werden.

Ich kodiere Routen bereits als benannte Gruppen, aber der Unterschied hier ist, dass die Schließung Ihnen erlaubt, eine Gruppe an einen bestimmten Controller zu binden. Dies wird keinen Unterschied machen, wenn Sie den Ansatz der aufrufbaren Controller (eine ganze Menge mehr Dateien, aber potenziell lockerere Kopplung), aber wenn Sie so etwas wie eine REST-API, die Standard-CRUD-Operationen zum Beispiel tut haben - das sieht schön in den Code. Nehmen Sie zum Beispiel diesen Controller:

Class ReportController extends Controller
{
	public function index(){}
	public function store(){}
	public function delete(){}
	public function show(){}
}

Mit der Controller-Gruppierung können Sie nun die Controller-Methoden in die Routes-Datei verpacken:

Route::controller(ReportController::class)->group(function () {
	Route::get('/reports', 'index');
	Route::post('/reports', 'store');
	Route::delete('/reports/{id}', 'delete');
	Route::get('/reports/{id}', 'show')
}

Route List CLI-Ausgabe

Apropos Routen, die Ausgabe von routes:list wurde geändert, um eine entwicklerfreundlichere Ansicht zu erhalten:

Screenshot of the new route list output from Laravel's console

Forced Scope Bindungen

Dies ist eine nette kleine Änderung, die die Modellbeziehungen innerhalb der Pfadbindung in einer viel klareren Implementierung bindet. Zuvor konnten Sie eine erzwungene Bereichsbindung durch Hinzufügen eines benutzerdefinierten Schlüssels in einem untergeordneten Datensatz erreichen:

Route::get('/users/{user}/reports/{report:id}', function (User $user, Report $report) {
	return $report;
})

Ohne die Verwendung dieses benutzerdefinierten Schlüssels würden keine Modellbeziehungen erzwungen werden, d. h. solange Benutzer und Bericht gültige Schlüssel sind, würde die $report Beispielentität zurückgeben, auch wenn sie keine Beziehung hat (z. B. Model::hasOne(User::class))

Jetzt haben wir eine Methode, die diese Logik auf eine viel eindeutigere Weise ermöglicht:

Route::get('/users/{user}/reports/{report}', function (User $user, Report $report) {
	return $report;
})->scopeBindings();

Enums

PHP8.1 wurde mit der neuen enums Klasse ausgeliefert, die als Objekt mit statisch aufgerufenen Rückgabewerten behandelt werden kann oder eine "backed enumeration" sein kann, die einen Wert enthält. Ich habe gesehen, wie Derek Rethans diese Funktion auf der Bühne der PHPUK 2022 vorgestellt hat.vorgestellt hat, und ich muss sagen, dass sie sich aus unserer Sicht bei Vonage als äußerst nützlich erweisen könnte. Da wir uns mit Sprachanrufen und Messaging beschäftigen, sind viele dieser Funktionen im PHP SDK haben statische Eigenschaften, um den Status zu definieren und abzurufen (z. B. der Status dieser SMS ist "0"). Enums haben das Potenzial, einen zugehörigen Typ zu haben, anstatt eine umfangreiche Liste statischer Eigenschaften.

Mit der Einführung von Enums wurden einige Laravel 9-Funktionen geschrieben, um diese Vorteile zu nutzen.

Attributbesetzung Enums

Ich habe an einem Projekt gearbeitet, bei dem dies wirklich eine Menge Kopfschmerzen erspart hätte. Alles in einer ziemlich großen MySQL-Datenbank wurde von einer "Event"-Basisklasse/Datenbanktabelle erweitert, wobei die erweiterten Entitäten durch MySQL-Enums eingeschränkt wurden. Klingt doch gut, oder? Als wir die Plattform erweiterten, musste eine neue Enum hinzugefügt werden, was einen Neuindex in einer Tabelle mit mehreren hundert Millionen Datensätzen auslöste. Das kippte jedes Mal.

Überlegen Sie, wie Sie eine Migration für eine Enum-Tabellenspalte schreiben würden:

$table->enum('eventType', ['SpotifyEvent', 'VideoEvent', 'AppleEvent'])

OK, also jedes Mal, wenn Sie eine neue Aufzählung hinzufügen, muss eine neue Migration durchgeführt werden, und Sie müssen das Modell aktualisieren.

In Laravel 9 können Sie stattdessen eine Enum-Klasse angeben und so die Logik in Ihrem Backend-Code und nicht in Ihrer Datenbank belassen. Dies ist zwar aus Sicht der Datenbank ein Nachteil, da die Speicherung ineffizient ist, aber der Code ist dadurch deutlich lesbarer. Ihre Migration würde also stattdessen eine varchar-Spalte sein:

$table->string('eventType')->default('SpotifyEvent');

Und Ihre Logik würde in einer zurückgesetzten Enum-Klasse sitzen, die innerhalb des Models referenziert wird $casts Array referenziert wird:

enum EventType: string {
	case SpotifyEvent = 'spotify';
	case VideoEvent = 'video';
	case AppleEvent = 'apple';
}

class EventEntry extends Model
{
	protected $casts = [
		'eventType' => EventType::class
	];
}

Damit ist unser Casting in und aus der Datenbank abgeschlossen: Sie können es mit tinker ausprobieren:

php artisan tinker

\App\Model\EventEntry::first()->eventType->value;

Und Ihr String-Wert wird zurückgegeben. eventType wird tatsächlich ein Enum-Objekt zurückgeben, deshalb müssen wir das value Attribut hinzufügen, um die zurückgegebene Eigenschaft herauszubekommen.

Routenbindung mit Enums

Sie können auch Enum-Klassen innerhalb der Routenbindung verwenden. Angenommen, Sie möchten die folgende Route einschränken:

Route::get('events/eventType');

Sie können nun die Enum-Klasse wie folgt binden:

Route::get('/events/{eventType}', function (EventType $eventType) {
	return $eventType->value;
});

Testabdeckung

Die Rückkehr zu Xdebug, um es in meiner täglichen Entwicklungs-Toolchain zu verwenden war eine Art Offenbarung nach Jahren der Verwendung von die() und dd() Debuggen. Als ich mit der Arbeit an unserem PHP-SDK begann, sah ich, dass unser CI CodeCov verwendet, um sicherzustellen, dass Pull Requests nicht ohne ausreichende Abdeckung innerhalb der Testsuite zusammengeführt werden können. Die Abdeckung erfolgt mit Hilfe von Xdebug, Sie müssen also zunächst die Abdeckung in Ihrer .ini-Datei aktivieren:

xdebug.mode=develop,debug,coverage

Wenn Sie nun artisan test --coverageausführen, erhalten Sie einen Bericht mit der Abdeckung Ihrer Anwendung:

Screenshot of the new test coverage output from Laravel's console

Ziemlich toll, oder?

Und was kommt als Nächstes?

Diese Version ist ein weiterer Meilenstein auf der Reise von Laravel, aber was wirklich erstaunlich ist, ist das erweiterte Ökosystem, das um Laravel herum aufgebaut wurde - Vapor, Breeze, Octane, Sail, Horizon... die Liste geht weiter. Was ich an der ständig wachsenden Liste von Laravel-Projekten spannend finde, ist seine Aufnahme in die der PHP-Stiftungdie im Zuge des Rückzugs von Nikita Popovs Rückzug aus der PHP-Kernentwicklung. Zusammen mit Symfony ist es ziemlich klar, dass die unsterbliche Zeile "PHP ist tot" nicht weiter von der Wahrheit entfernt sein könnte.

Teilen Sie:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondeSenior PHP Entwickler Advocate

Als ausgebildeter Schauspieler mit einer Dissertation in Standup-Comedy bin ich über die Meetup-Szene zur PHP-Entwicklung gekommen. Man findet mich, wenn ich über Technik spreche oder schreibe, oder wenn ich seltsame Platten aus meiner Vinylsammlung spiele oder kaufe.