PHP Runtime: Die Zukunft von PHP-Applikationen

The future is now!

The future is now!

PHP Runtime: Die Zukunft von PHP-Applikationen

The future is now!


Mit dem Release von Symfony 5.3 Ende Mai 2021 wurde unter anderem auch die Runtime-Komponente vorgestellt [1]. Dieser Artikel gibt eine erste Übersicht über das Projekt, das auf der neuen Symfony-Komponente aufbaut, und wirft einen Blick in die Glaskugel, wie sich PHP Runtime auf die Zukunft von PHP-Anwendungen auswirken kann [2].

Bevor wir über die Zukunft sprechen, verschaffen wir uns zunächst einen Überblick darüber, wie traditionelle PHP-Applikationen heutzutage ablaufen. Die Verarbeitung eines HTTP-Requests in PHP durchläuft üblicherweise die folgenden Schritte:

  • Aufruf des Webservers (Apache [3], Caddy [4], NGINX [5] etc.) mit einer Clientanfrage

  • Weitergabe der Anfrage an den PHP-Prozessmanager

  • Entgegennahme der Anfrage durch den PHP-Prozess

  • Aufruf vom Front Controller Script (index.php)

  • Erstellung einer Framework-/projektspezifischen Instanz (Klasse/Service)

  • Verarbeitung der Anfrage und senden einer Antwort durch die Applikationsinstanz

  • Abschließen und Beenden des PHP-Prozesses inklusive der Applikationsinstanz

  • Weiterleiten der Antwort vom Webserver an den Client

Das ist der Prozess, der für jede traditionelle PHP-Applikation abläuft – egal, ob es sich um Symfony, Laravel, Laminas, Spiral oder ein anderes Framework handelt. Wie sich dieser Ablauf in Zukunft ändern könnte, werden wir im Laufe dieses Artikels analysieren.

Blick in die Zukunft

Fragt man Tobias Nyholm, Mitglied des Symfony-Core-Teams, wie eine PHP-Applikation im Jahr 2022 aussieht, werden von ihm folgende Punkte als Erstes aufgeführt:

  1. Verwendung einer Filesystem-Abstraktion

  2. Verwendung von Redis/Memcache für Sessions

  3. keine Verwendung von Superglobals ($_SERVER, $_GET, $_POST, …)

In den ersten zwei Punkten geht es um Cloud-Readiness und Betrieb von PHP-Applikationen in einem Multi-Server-Set-up. Hier sollten keine Dateien lokal gespeichert werden, bzw. durch einfache Konfiguration sollte ein externer Datenspeicher genutzt werden können. Durch die Verwendung einer Filesystem-Abstraktion wie Flysystem und der Verwendung der PHP-Redis-Extension für Sessions lässt sich das bewerkstelligen [7].

Punkt drei, keine Verwendung von Superglobals, ist für die Verwender von modernen Frameworks wie Symfony, Laravel, Laminas, Spiral etc., die auf PSR 7 oder dem HttpFoundation-Paket aufbauen, schon längst kein Thema mehr und dadurch für diese nichts wirklich Neues. Der vierte von Tobias Nyholm genannte Punkt ist folgender: Verwendung der Symfony Runtime.

Die Symfony-Runtime-Komponente findet Anwendung im Front Controller und übernimmt das Starten der Applikation. Am besten lässt sich das veranschaulichen, wenn wir einen Blick auf den Front Controller von Symfony mit Symfony Runtime (ab Symfony 5.3) und ohne Symfony Runtime (bis Symfony 5.2) werfen, was wir in Listing 1 tun.

Listing 1: Front Controller ohne Symfony Runtime (bis Symfony 5.2)

<?php
 
use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\HttpFoundation\Request;
 
require dirname(__DIR__).'/vendor/autoload.php';
 
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
 
if ($_SERVER['APP_DEBUG']) {
  umask(0000);
 
  Debug::enable();
}
 
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);

Bei genauerem Hinsehen auf diesen Front Controller fällt auf, dass hier auf Superglobals zugegriffen wird – mehrmals auf die $_SERVER und indirekt auch auf weitere $_SERVER-Variablen im Aufruf von Request::createFromGlobals(). Ebenfalls kann die Logik hier Fehler beinhalten. Da der Front Controller im Projekt liegt, müsste jeder selbst einen hier auftauchenden Fehler beheben. In der Vergangenheit wurden Anpassungen vorgenommen wie das Einführen einer neueren Debug-Komponente oder das Dotenv-Handling, was manuell oder durch ein FrameworkBundle Recipe upgedated werden mussten. Ein Blick auf den neuen Front Controller mit der Symfony Runtime zeigt, dass sich der Front Controller um einiges vereinfachen lässt (Listing 2).

Listing 2: Front Controller mit Symfony Runtime (ab Symfony 5.3) [9]

<?php
 
use App\Kernel;
 
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
 
return function (array $context) {
  return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

In Listing 2 sehen wir, dass nur noch eine Funktion zurückgegeben wird. Die andere Logik, die fehleranfällig sein könnte, wird von der Symfony-Runtime-Komponente verwaltet. Eventuelle Fehler im Front Controller können direkt vom Symfony-Team für alle Applikationen behoben werden. Das Starten der Anwendung wird von der sogenannten Runtime übernommen, die einen oder mehrere Runner zur Verfügung stellt. Mit der Runtime-Komponente werden folgende Runner mitgeliefert:

  • HttpKernelRunner

  • ResponseRunner...