Digitalagentur für Business Software aus Kiel

Konzept und grundlegende Änderungen in Symfony 4

Veröffentlicht von Henrik Braune am 04.06.2017

Henrik Braune

Symfony 4, das sich derzeit in der Entwicklung befindet, wird einen radikal modularen Ansatz verfolgen, der sich deutlich von den bisherigen Symfony-Versionen unterscheidet und das Ziel verfolgt, den neuen Anforderungen an Web-Frameworks gerecht zu werden.

Der Weg zu Symfony 4

Zum Release von Symfony 2 wurde das Framework vollständig neu entwickelt. Die darin enthaltene Idee, das Framework als Klammer um eine Vielzahl unabhängiger Komponenten zu gestalten, ist seitdem einer der Gründe für die Erfolgsgeschichte. Die Symfony-Komponenten sind seitdem in die Architektur vieler bekannter Open-Source Projekte (z.B. Drupal, Shopware, Oro CRM, Laravel, TYPO3) eingeflossen.

Bis zur Version 2.8 im Jahr 2015 wurde Symfony um viele sinnvolle Features und Verbesserungen erweitert. Der Sprung auf die Version 3 signalisierte einen größeren Bruch und mehr Neuerungen. In Wirklichkeit jedoch wurden für Symfony 3.0 keine Features ergänzt, sondern lediglich Funktionen entfernt, die seit 2.8 als "deprecated" markiert waren. Die weiteren Releases der Version 3 umfassen seitdem erneut neue Features, Bundles und Komponenten.

Symfony 4 wird ein Bruch in der beschrieben stetigen Weiterentwicklung sein. Fabien Potencier bringt es in seinem ersten Beitrag zu Symfony 4 auf folgende einfache Formel:

Symfony 4.0 = Symfony 3.0 + alle Features aus 3.x - "deprecated" Features + eine neue Art, Applikationen zu entwickeln

 
Auf die "neue Art, Applikationen zu entwickeln", möchten wir im Folgenden hauptsächlich eingehen.

Schwächen von Symfony 2.x und 3.x

Potencier beschreibt in seinem Beitrag Aspekte der Symfony-Architektur, die aus Sicht der Entwickler suboptimal sind:

  • Die Installation und Nutzung von Bundles ist mühsam. Um Ein Bundle einzusetzen, sind mehrere Schritte notwendig: Das Paket wird über den Composer installiert, anschließend muss das Bundle im AppKernel registriert werden. Zuletzt ist eine Integration in das Routing und die Konfiguration an sich notwendig.
  • Ein Bundle wieder zu deinstallieren, erfordert die gleichen beschriebene Schritte in umgekehrter Reihenfolge und ist in der Konsequenz auf aufwendiger als notwendig.

Noch viel wichtiger – und diese Einschätzung teilen wir aus der Erfahrung mit vielen Kundenprojekten – ist, dass das Framework noch immer darauf ausgelegt ist, klassische Webanwendungen abzubilden, deren Views auf der Backend-Seite gerendert und anschließend ausgeliefert werden. Symfony ging bisher immer von einem Standard-Set an klassischen Anforderungen aus. In der Regel (und das ist auch bei uns der Fall) entstehen Applikationen inzwischen aber als Kombination aus unterschiedlichen Frontends (die dann z.B. mit Angular 2 umgesetzt werden) und einer (oder mehrerer) API´s. In diesem Zusammenhang wird oft viel Aufwand betrieben, um Symfony für den jeweiligen Zweck anzupassen – oder es wird auf ein Micro-Framework wie Silex zurückgegriffen. Die "Standard Edition" von Symfony umfasst das vollständige Framework und trifft eine Vielzahl von Grundannahmen. In der Folge muss die Distribution je nach Art des Projektes "entschlackt" werden.

Die Idee von Symfony 4

Symfony 4 wird weniger Grundannahmen treffen und viel weniger Abhängigkeiten haben. Es wird nicht mehr nötig sein, ein "fettes" Framework von seinen Abhängigkeiten zu befreien. Vielmehr ist Symfony 4 vom Grundgedanken geprägt, schlank zu starten und Abhängkeiten so einfach wie möglich zu ergänzen. Sobald man zukünftig ein neues Symfony-Projekt erstellt, wird dies initial aus nur einer Datei bestehen – der composer.json. Das neue Composer-Plugin Symfony Flex wird hier eine maßgebliche Rolle spielen und Abhängigkeiten verwalten. Sogenannte "Rezepte" ("Recipes") beinhalten standardisierte Prozesse, die bei der Installation von Paketen ausgeführt werden. Rezepte verfügen dabei immer über ein "Makefile" und ein Manifest. Für das JWT Authentication Bundle beinhaltet die manifest.json beispielsweise folgende Definition:

{
    "bundles": {
        "Lexik\\Bundle\\JWTAuthenticationBundle\\LexikJWTAuthenticationBundle": ["all"]
    },
    "copy-from-recipe": {
        "etc/": "%ETC_DIR%"
    },
    "aliases": ["jwt-auth"],
    "env": {
        "#1": "Key paths should be relative to the project directory",
        "JWT_PRIVATE_KEY_PATH": "%ETC_DIR%/jwt/private.pem",
        "JWT_PUBLIC_KEY_PATH": "%ETC_DIR%/jwt/public.pem",
        "JWT_PASSPHRASE": "%generate(secret)%"
    }
}

 

Ein konkretes Beispiel: Wenn beispielsweise die Formular-Komponente genutzt werden soll, kann diese wie bisher über den Composer hinzugefügt werden. Symfony 4 erkennt die Abhängigkeit und nimmt eine Auto-Konfiguration des Formular-Bundles vor. Weder ein Eintrag im AppKernel noch eine Konfiguration in der config.yml werden notwendig sein. 

Keine Bundles

Eine erhebliche Änderung in der Architektur von Applikationen mit Symfony ist die ausgesprochene Empfehlung, diese nicht mehr in Bundles zu modularisieren. Dies betrifft natürlich nur den projektbezogenen Code unter /src. Symfony baut weiterhin auf einem Fundament aus vielen Komponenten auf. Damit folgt die Empfehlung der gängigen Praxis vieler Entwickler, nur in einem AppBundle zu arbeiten. So wie die Diskussion im Core-Team nicht eindeutig endete, sind auch wir eher der Überzeugung, dass eine Strukturierung nach Bundles innerhalb des Projekt-Namespaces Sinn macht, sofern die Module wirklich geringe gegensetige Abhängigkeiten aufweisen.

Umgebungsvariablen

Anstelle der app/config/parameters.yml werden Symfony 4-Anwendungen über die "Environment variables" konfiguriert (wobei es weiterhin möglich sein wird, die parameters.yml zu nutzen). Die neue Dotenv-Komponente wird in Symfony die Umgebungsvariablen (sei es über .env-Dateien oder über den Webserver gesetzte Variablen) verarbeiten und ist auch bereits für die 3.3-Version verfügbar. Über die Verwendung der Umgebungsvariablen wird es darüber hinaus nicht mehr notwendig sein, die Umgebung von Konsolen-Befehlen zu definieren.

Frontend Controller

Durch die Nutzung der Umgebungsvariablen ist es möglich, nur noch einen einheitlichen Frontend-Controller einzuführen. Anstelle der bekannten app.php und app_dev.php wird Symfony 4 nur noch über die index.php innerhalb des Web-Verzeichnisses verfügen.

Makefile

Weiter oben wurde bereits angedeutet, dass die neuen "Rezepte" über ein Manifest und ein Makefile verfügen. Symfony 4 wird "make" nutzen, um definierte Prozesse auszuführen, beispielsweise das Ausführen von Tests oder das Leeren von Caches. 

Die neue Verzeichnisstruktur

Symfony 4 wird über eine neue Struktur der Verzeichnisse verfügen. Einige Verzeichnisse bleiben erhalten, andere wurden ersetzt oder kommen neu hinzu:

  • /tests
    Tests
  • /templates
    Templates
  • /etc
    Entspricht in etwa dem früheren /app/config
  • /src
    Projekt-Code
  • /var
    Temporäre Dateien
  • /web
    Web-Dateien

Die Verzeichnisse sind teilweise optional. Bei einer API beispielsweise wird kein templates-Verzeichnis notwendig sein.

Quick-Start: Symfony 4 Projekt

Ein neues Symfony 4 Projekt kann über folgenden Befehl initialisiert werden:

 

composer create-project "symfony/skeleton:^3.3" s4demo

Die dabei geladene composer.json enthält folgenden Inhalt:


{
    "name": "symfony/skeleton",
    "type": "project",
    "license": "proprietary",
    "description": "Project description",
    "require": {
        "php": "^7.1.3",
        "symfony/flex": "^1.0",
        "symfony/framework-bundle": "^3.3",
        "symfony/yaml": "^3.3"
    },
    "require-dev": {
        "symfony/dotenv": "^3.3"
    },
    "config": {
        "platform": {
            "php": "7.1.3"
        },
        "preferred-install": {
            "*": "dist"
        },
        "sort-packages": true
    },
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "App\\Tests\\": "tests/"
        }
    },
    "scripts": {
        "auto-scripts": [
        ],
        "post-install-cmd": [
            "@auto-scripts"
        ],
        "post-update-cmd": [
            "@auto-scripts"
        ]
    },
    "conflict": {
        "symfony/symfony": "<3.3",
        "symfony/twig-bundle": "<3.3",
        "symfony/debug": "<3.3"
    },
    "extra": {
        "symfony": {
            "id": "",
            "allow-contrib": false
        }
    }
}

 

Nachdem der Composer das Projekt initialisiert hat, werden die definierten Abhängigkeiten installiert und konfiguriert. Dabei werden die bereits beschrieben Konzepte von Symfony Flex angewendet. Eine Schritt für Schritt-Anleitung für den Start einer Demo und weitere Details finden sich im Blog Artikel "Symfony 4: A quick Demo".

© 2017, Braune Digital GmbH, Niemannsweg 69, 24105 Kiel, +49 (0) 431 55 68 63 59