Von PHP 8.2 auf 8.4: jetzt patchen, dann umsteigen

PHP 8.2 endet am 31.12.2026. Installieren Sie heute 8.2.35 gegen PHP2Shell und wechseln Sie dann auf 8.4: die Änderungen in 8.3 und 8.4 und die Scan-Befehle.

Zwei Aufgaben, in dieser Reihenfolge

PHP 8.2 bekommt Sicherheitsupdates bis zum 31. Dezember 2026, also noch etwa zehn Wochen. Danach gibt es keine offiziellen Releases mehr. Siehe PHP 8.2.

  1. Heute: Installieren Sie 8.2.35. Diese Version enthält die PHP2Shell-Fixes für CVE-2026-109618 und CVE-2026-109619. Starten Sie alle PHP-Prozesse neu und prüfen Sie die laufende Version.
  2. Bis zum Jahresende: Wechseln Sie auf 8.4 (Fix in 8.4.27). Dieser Zweig bekommt Sicherheitsupdates bis zum 31. Dezember 2028. Den Vergleich finden Sie unter Welche Version.

Erledigen Sie die erste Aufgabe auch dann, wenn die zweite Wochen dauert. Ein Patch-Release innerhalb eines Zweigs ist eine kleine Änderung. Der Sprung auf eine neue Minor-Version braucht Staging und Tests.

Hat Ihre Distribution oder Ihr Hoster 8.2.35 noch nicht ausgeliefert, zeigen die Paket-Anleitungen unter Fix, was welcher Anbieter veröffentlicht hat. Bei Shared Hosting fragen Sie den Hoster und lesen Shared Hosting.

Reihenfolge für den Umstieg

  1. Sichern Sie Dateien und Datenbank. Testen Sie eine Wiederherstellung.
  2. Richten Sie eine Staging-Kopie auf 8.4 ein, mit denselben Erweiterungen und denselben php.ini-Werten.
  3. Aktualisieren Sie CMS, Framework, Plugins und Composer-Pakete auf Versionen, die 8.4-Unterstützung angeben. composer outdated und composer why-not php 8.4 zeigen, was Sie blockiert.
  4. Führen Sie den Kompatibilitäts-Scan unten aus.
  5. Betreiben Sie Staging mit error_reporting = E_ALL und log_errors = On. Testen Sie Logins, Formulare, Uploads, Checkout und geplante Jobs. Lesen Sie das Log.
  6. Stellen Sie die Produktion um, starten Sie alle PHP-Prozesse neu und prüfen Sie die Version.
  7. Halten Sie 8.2 ein paar Tage lang mit einem Klick im Panel erreichbar.

Ihre Logs unter 8.2 zeigen schon die Deprecations von 8.2, vor allem dynamische Properties und utf8_encode(). Beheben Sie diese zuerst, denn unter 8.4 sind sie weiterhin als veraltet markiert.

Änderungen in PHP 8.3

8.3 bricht wenig. Die folgenden Punkte tauchen in echten Projekten auf.

  • range() ist strenger. Eine Schrittweite von 0, eine negative Schrittweite bei aufsteigendem Bereich sowie Unendlich oder NAN werfen ValueError. Gemischte Aufrufe wie range(5, 'z') erzeugen eine Warnung.
  • number_format() rundet bei negativem $decimals jetzt vor dem Dezimalpunkt, statt den Wert zu ignorieren.
  • Negativer Array-Index. Nach $a[-5] = 'x' auf einem leeren Array bekommt das nächste $a[] den Index -4 statt 0.
  • Datumsfehler nutzen jetzt die Klassen DateError und DateException statt Warnungen. Prüfen Sie Code, der das Parsen von Daten in try/catch einschließt.
  • Tiefe Rekursion kann einen Error werfen, wenn der Call Stack an seine Grenze kommt.
  • Veraltet: get_class() und get_parent_class() ohne Argumente, assert_options() mit den INI-Einstellungen assert.*, ReflectionProperty::setValue() mit einem Argument und der Modus MT_RAND_PHP.
  • Inkrementieren nicht-numerischer Strings ist „soft deprecated“. Verwenden Sie in neuem Code str_increment().
  • Entfernt: die INI-Direktive opcache.consistency_checks. Löschen Sie sie aus der php.ini, sonst gibt es Meldungen beim Start.

Änderungen in PHP 8.4

  • Implizit nullable Parameter. function f(Foo $a = null) ist veraltet. Schreiben Sie ?Foo $a = null. Veraltete Bibliotheken lösen das bei jeder Anfrage aus. Aktualisieren Sie die Pakete, bevor Sie Ihren eigenen Code beurteilen.
  • E_STRICT ist entfernt als Fehlerstufe. trigger_error() mit E_USER_ERROR ist veraltet, werfen Sie stattdessen eine Exception.
  • CSV-Funktionen. Sich auf den Standardwert des Arguments escape von fgetcsv(), fputcsv() und str_getcsv() zu verlassen, ist veraltet. Übergeben Sie escape ausdrücklich.
  • Nach PECL verschoben: IMAP, OCI8, PDO_OCI und PSpell. Wenn Sie imap_*-Funktionen aufrufen, installieren Sie das PECL-Paket oder wechseln die Bibliothek.
  • Session-Einstellungen. Das Ändern von session.sid_length, session.sid_bits_per_character, session.use_only_cookies, session.use_trans_sid, session.trans_sid_tags, session.trans_sid_hosts oder session.referer_check ist veraltet. Das gilt auch für die Konstante SID.
  • mysqli: mysqli_ping(), mysqli_kill() und mysqli_refresh() sind veraltet.
  • round() wirft ValueError bei ungültigem Modus, und das alte Vorrunden wurde entfernt. Einige Grenzfälle liefern deshalb andere Ergebnisse.
  • exit() verhält sich wie eine Funktion. Es beachtet strict_types und wirft TypeError bei ungültigem Typ.
  • Neue JIT-Standardwerte. Wenn Sie JIT nur über opcache.jit_buffer_size eingeschaltet haben, setzen Sie zusätzlich opcache.jit.
  • bcrypt-Kosten liegen standardmäßig bei 12 statt 10. Logins dauern länger. Bestehende Hashes werden weiterhin geprüft.
  • Namenskollisionen. Eine in 8.4 neu hinzugekommene Funktion oder Klasse bricht Code, der denselben Namen definiert. Schützen Sie eigene Hilfsfunktionen mit function_exists().
  • Mindestversionen der Bibliotheken: libcurl 7.61.0, libxml2 2.9.4 und OpenSSL 1.1.1. Prüfen Sie ältere Server. Für mod_php ist Apache 2.4 das Minimum.

Befehle für Scan und Korrektur

Führen Sie diese Befehle auf einem Arbeitsrechner oder in der CI aus.

composer config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer require --dev phpcompatibility/php-compatibility:"^10.0.0@dev"
vendor/bin/phpcs -i

vendor/bin/phpcs -ps --standard=PHPCompatibility --runtime-set testVersion 8.2-8.4 \
  --ignore='*/vendor/*,*/node_modules/*' --report-full=compat-report.txt .

Der Bereich 8.2-8.4 meldet alles, was eine der beiden Versionen betrifft. Der Code bleibt so sicher, solange beide parallel laufen. Nach der Umstellung nehmen Sie --runtime-set testVersion 8.4. Die Angabe ^10.0.0@dev ist die aus der README von PHPCompatibility, Stand 22.10.2026. Sie setzt PHP_CodeSniffer 4.0.2 oder neuer voraus.

Rector kann einen Teil der Funde beheben, etwa explizite nullable Typen. Sehen Sie sich den Diff an, bevor Sie committen.

composer require rector/rector --dev
vendor/bin/rector process --dry-run
vendor/bin/rector process

Schreiben Sie return RectorConfig::configure()->withPaths([__DIR__ . '/src'])->withPhpSets(); in die rector.php. Rector liest die PHP-Version dann aus der composer.json.

Schreiben Sie nie Code in Plugins oder Themes um, die Sie nicht selbst geschrieben haben. Aktualisieren Sie sie. Für WordPress siehe PHP-Version ändern.

Zuletzt geprüft am 22. Oktober 2026.