Ihre Anwendung läuft seit Jahren stabil auf Symfony 4. Die Fachlogik stimmt, die Kunden sind zufrieden, aber Composer meldet bei jedem update mehr Warnungen, Sicherheits-Patches gibt es nicht mehr, und neue Bibliotheken setzen längst PHP 8 voraus. Die gute Nachricht: Ein System, das lange produktiv war, ist kein Sanierungsfall. Es ist der Beweis, dass Ihre Domänenlogik funktioniert. Das Problem sitzt fast immer nicht im Kern, sondern im Framework-Code drumherum. Genau den kann man austauschen, ohne das Erprobte wegzuwerfen.
Dieser Artikel zeigt den sicheren Pfad für ein Symfony 4 auf 6 Upgrade: nicht als einen großen Sprung, sondern als Kette kleiner, jederzeit deploybarer Schritte.
Warum ein direkter Symfony 4 auf 6 Upgrade der falsche Weg ist
Springen Sie nicht in einem Rutsch von 4.x auf 6.x. Symfony ist für schrittweise Migration entlang der Minor-Versionen ausgelegt, und dieser Weg ist deutlich risikoärmer als ein Big-Bang-Upgrade.
Der Grund liegt im Deprecation-Mechanismus von Symfony. Funktionen, die in einer Major-Version entfernt werden, sind in der vorherigen Version bereits als deprecated markiert und lösen zur Laufzeit Meldungen aus. Der offizielle Pfad lautet deshalb: erst auf die letzte Minor-Version einer Major-Reihe gehen, dort alle Deprecations beseitigen, und dann auf die nächste Major hochziehen. Konkret bedeutet das die Route 4.4 → 5.4 → 6.4. Sowohl 4.4 als auch 5.4 sind LTS-Versionen und bilden stabile Zwischenstationen, auf denen Sie produktiv bleiben können, solange Sie brauchen.
PHP-Version zuerst: das unterschätzte Nadelöhr
Klären Sie Ihre PHP-Version vor dem ersten Composer-Befehl, denn sie limitiert, welche Symfony-Version Sie überhaupt installieren können. Symfony 6.0 setzt mindestens PHP 8.0.2 voraus, 6.4 empfiehlt PHP 8.1 oder höher.
In der Praxis ist der Sprung von PHP 7.x auf 8.x oft die härtere Migration als der Framework-Wechsel selbst. Rechnen Sie mit realen Breaking Changes:
- Strengere Typprüfung: PHP 8 wirft
TypeError, wo 7.x still konvertiert hätte. Vergleiche wie0 == "foo"liefern jetztfalsestatttrue. - Entfernte Funktionen:
each(),create_function()und die altemysql_*-Familie sind weg. - Geänderte Fehlerbehandlung: Manche Warnings wurden zu Errors hochgestuft, was Code stoppt, der vorher weiterlief.
Nehmen Sie die PHP-Anhebung als eigenständigen Schritt vor dem Symfony-Upgrade in Angriff. Zwei große Umbauten gleichzeitig zu debuggen, macht die Fehlersuche unnötig schwer.
Die Werkzeuge, die die eigentliche Arbeit machen
Zwei Tools tragen den größten Teil der mechanischen Last. Nutzen Sie beide von Anfang an, statt Änderungen von Hand nachzuziehen.
Symfony Flex und die Upgrade-Rezepte übernehmen Konfigurationsänderungen. Nach einem composer recipes:update gleicht Flex Ihre Dateien in config/ mit den aktuellen Empfehlungen ab. Das ist der Grund, warum sich Symfony sauberer aktualisieren lässt als viele andere Frameworks.
Rector automatisiert Code-Änderungen im PHP selbst. Mit dem Set SymfonySetList passt es veraltete Klassennamen, Attribute und Signaturen automatisch an, etwa den Wechsel von Annotations zu PHP-8-Attributen bei Routing und Doctrine. Rector nimmt Ihnen keine Architekturentscheidung ab, aber es erledigt die stumpfe Fleißarbeit über hunderte Dateien zuverlässig.
Wie räume ich Deprecations vor dem Major-Sprung auf?
Behandeln Sie jede Deprecation-Meldung auf 4.4 als Pflichtaufgabe, bevor Sie auf 5.4 gehen. Was auf der alten Minor nur eine Warnung ist, wird auf der nächsten Major zum harten Fehler.
Symfony macht diese Meldungen sichtbar. Der DeprecationErrorHandler in Ihrer Testsuite zählt sie, und das Profiler-Panel im Dev-Modus listet sie pro Request auf. Ein pragmatischer Ablauf pro Version:
composer update "symfony/*"auf die nächste Minor innerhalb der Major-Reihe.- Testsuite laufen lassen und die Deprecation-Zusammenfassung auswerten.
- Meldungen abarbeiten, idealerweise mit Rector, wo möglich.
- Erst wenn die Suite deprecation-frei ist, den
composer.json-Constraint auf die nächste Major heben.
Dieser Zyklus ist der Kern des sicheren Upgrade-Pfads. Jede Zwischenstation ist ein Zustand, den Sie deployen könnten, wenn Sie müssten.
Ohne Tests kein sicheres Upgrade
Ihre Tests sind während der Migration das Sicherheitsnetz, das bestätigt, dass die Fachlogik unverändert funktioniert. Fehlt dieses Netz, upgraden Sie blind.
Viele Legacy-Symfony-Projekte haben nur dünne Testabdeckung. Schreiben Sie in diesem Fall keine vollständige Unit-Suite nachträglich, das dauert zu lange. Setzen Sie stattdessen auf einige wenige Funktions- und Smoke-Tests, die die kritischen Pfade abdecken: Login, die drei bis fünf wichtigsten Formulare, der Checkout oder Ihr zentraler Geschäftsvorgang. Diese Tests beweisen nach jedem Schritt, dass die erprobte Logik weiterhin das Richtige tut. Genau darum geht es: nicht die Logik neu zu bauen, sondern das Framework unter ihr auszutauschen.
Typische Stolpersteine zwischen Symfony 4 und 6
Über die reinen Deprecations hinaus gibt es strukturelle Änderungen, die häufig Zeit kosten. Rechnen Sie mit diesen Bereichen:
- Security-Komponente: Das alte, komplexe Guard-Authenticator-System wurde durch das neue Authenticator-basierte Security-System abgelöst. Diese Umstellung ist oft der aufwendigste Einzelposten und selten vollständig automatisierbar.
- Konfiguration in YAML statt Annotations: Routing- und Validierungsmetadaten wandern zunehmend zu PHP-8-Attributen.
- Doctrine-Versionen: Neuere Symfony-Versionen erwarten neuere Doctrine-ORM- und DBAL-Versionen, die eigene Breaking Changes mitbringen. Behandeln Sie Doctrine als parallele Migrationsachse.
- Session- und Request-Handling: Direkte Zugriffe auf globale Session-Objekte wurden umgestellt; hier hilft der Profiler beim Aufspüren.
Praxis-Tipp: klein deployen, nicht sammeln
Der häufigste Fehler ist, alle Änderungen in einem monatelangen Feature-Branch zu sammeln und am Ende in einem großen Merge zu deployen. Dieser Branch driftet vom Produktivstand weg, Konflikte häufen sich, und im Fehlerfall wissen Sie nicht, welche der hunderten Änderungen schuld ist.
Gehen Sie den umgekehrten Weg. Jede Minor-Anhebung und jeder abgeschlossene Deprecation-Block ist ein eigener, überschaubarer Merge, der zeitnah in Produktion geht. So bleibt jeder Schritt für sich überprüfbar, und ein Rollback betrifft immer nur eine kleine, klar umrissene Änderung. Ein Upgrade in kleinen Schritten ist langsamer geplant, aber schneller und sicherer erledigt als der große Sprung.
Wenn Sie vor genau dieser Situation stehen, ein bewährtes Symfony-4-System, das den Sprung nach vorne braucht, unterstützt LegacyWerk bei der Planung und Durchführung solcher Upgrades, ohne die Logik neu zu erfinden, die längst funktioniert.