Wo Sie stehen
PHP 8.1 hat am 31. Dezember 2025 das End of Life erreicht. Für PHP2Shell (CVE-2026-109618 und CVE-2026-109619) hat das PHP-Projekt für 8.1 nur einen Backport-Branch im Quellcode veröffentlicht. Ein 8.1-Release mit den Fixes gibt es nicht. Die behobenen Releases sind 8.2.35, 8.3.36, 8.4.27 und 8.5.12. Der unterstützte Fix ist der Wechsel nach oben. Siehe PHP 8.1 und, falls Sie noch nicht wechseln können, was Sie in der Zwischenzeit tun können.
Ziel ist 8.4 (behoben in 8.4.27). Unter Welche Version Sie wählen sollten steht, warum nicht 8.2.
Wenn Sie von 7.4 oder 8.0 kommen, nutzen Sie die Anleitung von 7.4 auf 8.4. Sie deckt auch die Änderungen aus 8.0 und 8.1 ab.
Reihenfolge der Arbeit
- Sichern Sie Dateien und Datenbank und testen Sie die Wiederherstellung.
- Bauen Sie eine Staging-Kopie auf 8.4 mit denselben Extensions und
php.ini-Werten. - Aktualisieren Sie CMS, Framework, Plugins und Composer-Pakete auf Versionen, die 8.4 offiziell unterstützen.
composer why-not php 8.4listet die Blocker auf. - Führen Sie den Kompatibilitäts-Scan weiter unten aus.
- Beheben Sie zuerst die Funde aus der Liste für 8.2. Dynamic Properties und
utf8_encode()sind die üblichen Kandidaten. - Betreiben Sie Staging mit
error_reporting = E_ALLundlog_errors = On. Testen Sie Logins, Formulare, Uploads, Checkout und Cronjobs. Lesen Sie das Log. - Stellen Sie die Produktion um, starten Sie jeden PHP-Worker neu und prüfen Sie die laufende Version.
Der direkte Sprung von 8.1 auf 8.4 ist in Ordnung. Behandeln Sie die drei Versionsabschnitte unten als eine einzige Checkliste.
PHP 8.2
- Dynamic Properties sind deprecated. Wer einer Property einen Wert zuweist, die die Klasse nie deklariert hat, bekommt eine Deprecation. Deklarieren Sie die Property. Als Notlösung setzen Sie
#[\AllowDynamicProperties]an die Klasse.stdClassund Klassen mit__get()und__set()sind nicht betroffen. Am häufigsten kommt das aus alten Plugins. - Interpolation mit
"${var}"und"${expr}"ist deprecated. Nutzen Sie"{$var}"oder"$var". utf8_encode()undutf8_decode()sind deprecated. Nutzen Siemb_convert_encoding($s, 'UTF-8', 'ISO-8859-1')odericonv().- Relative Callables wie
"self::method"und["parent", "method"]sind deprecated. Nutzen Sie[self::class, 'method']oderself::method(...). - mbstring-Encodings.
Base64,QPrint,UuencodeundHTML-ENTITIESals mbstring-Encodings sind deprecated. Nutzen Siebase64_encode(),quoted_printable_encode(),convert_uuencode()undhtmlentities(). - Funktionen für Groß- und Kleinschreibung ignorieren die Locale.
strtolower(),strtoupper(),ucfirst(),ucwords()und ähnliche arbeiten jetzt wie in der Locale "C". Für Text mit Akzenten oder nicht lateinischer Schrift nehmen Sie diemb_*-Varianten. - Kleinere Änderungen.
str_split('')liefert[]statt[""].var_export()setzt einen führenden Backslash vor Klassennamen.glob()liefert ein leeres Array stattfalse, wennopen_basedirjeden Pfad sperrt.
PHP 8.3
8.3 bricht wenig. Deshalb taugt es als Ausweichziel.
range()ist strenger. Eine Schrittweite von0, eine negative Schrittweite bei aufsteigendem Bereich sowie INF oder NAN werfenValueError. Einige Aufrufe mit gemischten Typen wierange(5, 'z')erzeugen jetzt eine Warning.number_format()rundet bei negativem$decimalsjetzt vor dem Dezimalkomma, statt den Wert zu ignorieren.- Array-Keys. Nachdem einem leeren Array ein negativer Index zugewiesen wurde, nutzt das nächste
$a[]diesen Index plus eins statt0. - Datumsfehler nutzen die neuen Klassen
DateErrorundDateExceptionstatt Warnings. - Erkennung von Stack Overflows. Sehr tiefe Rekursion kann jetzt einen
Errorwerfen, bevor der Prozess abstürzt. - Deprecated:
get_class()undget_parent_class()ohne Argumente,assert_options()und die INI-Einstellungenassert.*,ReflectionProperty::setValue()mit nur einem Argument,ldap_connect()mit getrenntem Host und Port sowie der ModusMT_RAND_PHP. - Das Inkrementieren nicht numerischer Strings wie
$s = 'a'; $s++ist soft deprecated. Neuer Code solltestr_increment()aufrufen. - Entfernte INI-Einstellung:
opcache.consistency_checks.
PHP 8.4
- Implizit nullable Parameter.
function f(Foo $a = null)ist deprecated. Schreiben Sie?Foo $a = null. Veraltete Bibliotheken lösen das bei jedem Request aus, aktualisieren Sie also erst die Pakete, bevor Sie Ihren eigenen Code bewerten. E_STRICTist als Error-Level entfernt, undtrigger_error()mitE_USER_ERRORist deprecated. Werfen Sie stattdessen eine Exception.- CSV-Funktionen. Sich auf das Standardargument
escapevonfgetcsv(),fputcsv()undstr_getcsv()zu verlassen, ist deprecated. Übergeben Sie es explizit.str_getcsv()wirft außerdem, wenn Trennzeichen oder Begrenzer nicht genau ein Byte lang sind. - Nach PECL verschoben: IMAP, OCI8, PDO_OCI und PSpell. Installieren Sie sie aus PECL oder wechseln Sie auf eine andere Bibliothek.
- Session-INI-Änderungen sind deprecated für
session.sid_length,session.sid_bits_per_character,session.use_only_cookies,session.use_trans_sid,session.trans_sid_tags,session.trans_sid_hostsundsession.referer_check. Entfernen Sie sie ausphp.iniund.user.ini, sofern Sie sie nicht brauchen. - mysqli:
mysqli_ping(),mysqli_kill()undmysqli_refresh()sind deprecated. round()wirftValueErrorbei einem ungültigen Modus. Das alte Vorrunden ist entfallen, einige Randergebnisse ändern sich dadurch.exit()verhält sich wie eine Funktion. Es beachtet jetztstrict_typesund wirftTypeErrorbei einem ungültigen Typ.- Die JIT-Standardwerte haben sich geändert. Wenn Sie JIT nur durch Setzen von
opcache.jit_buffer_sizeeingeschaltet haben, müssen Sie jetzt zusätzlichopcache.jitsetzen. - Der bcrypt-Cost steht standardmäßig auf 12 statt 10, das Hashen von Passwörtern dauert also länger. Bestehende Hashes lassen sich weiter prüfen.
- Namenskollisionen. Jede in 8.4 neu hinzugekommene Funktion oder Klasse bricht Code, der sie bereits definiert. Sichern Sie Polyfills mit
function_exists()ab. - Höhere Mindestversionen für Bibliotheken: libcurl 7.61.0, libxml2 2.9.4, OpenSSL 1.1.1. Für
mod_phpist Apache 2.4 das Minimum.
Befehle zum Scannen und Beheben
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.1-8.4 \
--ignore='*/vendor/*,*/node_modules/*' --report-full=compat-report.txt .
testVersion 8.1-8.4 meldet Probleme, die irgendeine Version im Bereich betreffen. So bleibt der Code sicher, solange 8.1 und 8.4 nebeneinander laufen. Stellen Sie nach der Umstellung auf 8.4 um. Die Versionsangabe ^10.0.0@dev ist die, die das README von PHPCompatibility am 22. Oktober 2026 zeigt. Sie braucht PHP_CodeSniffer 4.0.2 oder neuer.
Rector kann einige Fixes automatisch anwenden, etwa explizite nullable Typen. Prüfen Sie jeden Diff.
composer require rector/rector --dev
vendor/bin/rector process --dry-run
vendor/bin/rector process
Mit return RectorConfig::configure()->withPaths([__DIR__ . '/src'])->withPhpSets(); in rector.php liest Rector die Zielversion aus composer.json.
Lassen Sie Plugin- und Theme-Code, der nicht Ihnen gehört, beim Scannen und Umschreiben außen vor. Aktualisieren Sie ihn stattdessen. Die Schritte für WordPress stehen unter PHP-Version ändern.
Zuletzt geprüft am 22. Oktober 2026.