- 
     
      matchist nun ein reserviertes Schlüsselwort.
 
- 
     
      mixedist nun ein reserviertes Wort, kann also nicht zur Benennung einer Klasse, Schnittstelle oder eines Traits verwendet werden und darf auch nicht in Namespaces verwendet werden.
 
- 
     
      Assertion-Fehler werden nun standardmäßig ausgelöst. Wenn das alte
      Verhalten gewünscht wird, kann in den INI-Einstellungen
      assert.exception=0gesetzt werden.
 
- 
     
      Methoden mit dem gleichen Namen wie die Klasse werden nicht mehr als
      Konstruktoren interpretiert. Stattdessen sollte die Methode
      __construct() verwendet werden.
      
- 
     
      Die Möglichkeit, nicht-statische Methoden statisch aufzurufen, wurde
      entfernt. Deshalb schlägt is_callable() fehl, wenn
      eine nicht-statische Methode mit einem Klassennamen geprüft wird (muss
      mit einer Objektinstanz überprüft werden).
      
- 
     
      Die Typumwandlungen (real)und(unset)wurden
      entfernt.
 
- 
     
      Die INI-Direktive track_errors
      wurde entfernt. Das bedeutet, dass php_errormsg nicht
      mehr verfügbar ist. Stattdessen kann die Funktion
      error_get_last() verwendet werden.
      
- 
     
      Die Möglichkeit, Konstanten ohne Berücksichtigung der Groß- und
      Kleinschreibung zu definieren, wurde entfernt. Das dritte Argument von
      define() kann nicht mehr truesein.
 
- 
     
      Die Möglichkeit, einen Autoloader mit einer
      __autoload()-Funktion anzugeben, wurde entfernt.
      Stattdessen sollte spl_autoload_register() verwendet
      werden.
      
- 
     
      Der Parameter errcontextwird nicht mehr an
      benutzerdefinierte Fehlerbehandlungen übergeben, die mit der Funktion
      set_error_handler() gesetzt wurden.
 
- 
     
      Die Funktion create_function() wurde entfernt.
      Stattdessen können anonyme Funktionen verwendet werden.
      
- 
     
      Die Funktion each() wurde entfernt. Stattdessen
      sollte foreachoder ArrayIterator verwendet
      werden.
 
- 
     
      Die Möglichkeit, die Bindung von this an Closures
      aufzuheben, die mittels Closure::fromCallable()
      oder ReflectionMethod::getClosure() aus einer
      Methode erzeugt wurden, wurde entfernt.
      
- 
     
      Die Möglichkeit, die Bindung von this an echte
      Closures aufzuheben, die this verwenden, wurde
      ebenfalls entfernt.
      
- 
     
      Die Möglichkeit, die Funktion array_key_exists() mit
      Objekten zu verwenden, wurde entfernt. Stattdessen können
      isset() oder property_exists()
      verwendet werden.
      
- 
     
      Das Verhalten der Funktion array_key_exists()
      entspricht bezüglich des Typs des Parameters keynun dem Verhalten der Funktion isset() und dem
      normalen Array-Zugriff. Alle Schlüsseltypen unterliegen nun den üblichen
      Einschränkungen und Array- und Objektschlüssel lösen einen
      TypeError aus.
 
- 
     
      Jedes Array, das eine Zahl n als ersten
      numerischen Schlüssel hat, verwendet n+1 für
      seinen nächsten impliziten Schlüssel, auch wenn
      n negativ ist.
      
      
- 
     
      Die voreingestellte Stufe von error_reporting ist nun
      E_ALL; zuvor warenE_NOTICEundE_DEPRECATEDausgeschlossen.
 
- 
     
      display_startup_errors
      ist nun standardmäßig aktiviert.
      
- 
     
      Die Verwendung von parent innerhalb einer Klasse, die keine
      übergeordnete Klasse hat, führt nun bei der Kompilierung zu einem
      schweren Fehler.
      
- 
     
      Der Operator @unterdrückt nun keine schweren Fehler
      (E_ERROR,E_CORE_ERROR,E_COMPILE_ERROR,E_USER_ERROR,E_RECOVERABLE_ERRORundE_PARSE) mehr. Error-Handler, die erwarten, dass
      error_reporting0ist, wenn@verwendet wird, sollten so angepasst werden, dass sie stattdessen die
      Fehler-Maske prüfen:
 
       
<?php
 // Dies ersetzen
 function my_error_handler($err_no, $err_msg, $filename, $linenum) {
 if (error_reporting() == 0) {
 return false;
 }
 // ...
 }
 
 // mit Folgendem
 function my_error_handler($err_no, $err_msg, $filename, $linenum) {
 if (!(error_reporting() & $err_no)) {
 return false;
 }
 // ...
 }
 ?>
 
 
      Darüber hinaus sollte in Produktivumgebungen darauf geachtet werden,
      dass keine Fehlermeldungen angezeigt werden, da dies zu
      Informationslecks führen kann. Es sollte sichergestellt werden, dass in
      Verbindung mit der Fehleraufzeichnung display_errors=Offverwendet wird.
 
- 
     
      #[wird nicht mehr als Beginn eines Kommentars
      interpretiert, weil diese Syntax nun für Attribute verwendet wird.
 
- 
     
      Vererbungsfehler aufgrund von inkompatiblen Methodensignaturen
      (Verletzung des Liskovschen Substitutionsprinzip, LSP) führen nun immer
      zu einem schweren Fehler. Vorher wurde in manchen Fällen eine Warnung
      erzeugt.
      
      
- 
     
      Die Rangfolge des Verkettungsoperators hat sich gegenüber
      Bitverschiebungen sowie Addition und Subtraktion geändert.
      
       
<?php
 echo "Summe: " . $a + $b;
 // wurde früher wie folgt interpretiert:
 echo ("Summe: " . $a) + $b;
 // wird nun interpretiert als:
 echo "Summe: " . ($a + $b);
 ?>
 
 
- 
     
      Ein Parameter mit einem Standardwert, der bei der Ausführung zu nullaufgelöst wird, wird nicht mehr implizit als nullbarer Parameter
      gekennzeichnet. Stattdessen muss explizit entweder ein nullbarer Typ
      oder der Standardwertnullverwendet werden.
 
       
<?php
 // Dies ersetzen
 function test(int $arg = CONST_RESOLVING_TO_NULL) {}
 // mit
 function test(?int $arg = CONST_RESOLVING_TO_NULL) {}
 // oder
 function test(int $arg = null) {}
 ?>
 
 
- 
     
      Einige Warnungen wurden in Error-Exceptions
      umgewandelt:
      
       
       - 
        Der Versuch, in eine Eigenschaft eines Nicht-Objekts zu schreiben.
        Zuvor wurde dadurch implizit ein stdClass-Objekt für null, false und
        leere Zeichenketten erstellt.
       
- 
        Der Versuch, ein Element an ein Array anzuhängen, für das bereits der
        Schlüssel PHP_INT_MAX verwendet wird.
       
- 
        Der Versuch, einen ungültigen Typ (Array oder Objekt) als
        Array-Schlüssel oder Zeichenketten-Offset zu verwenden.
       
- 
        Der Versuch, in einen Array-Index eines skalaren Wertes zu schreiben.
       
- Der Versuch, ein Nicht-Array/Traversable zu entpacken.
- 
        Der Versuch, auf unqualifizierte Konstanten zuzugreifen, die nicht
        definiert sind. Zuvor führten Zugriffe auf unqualifizierte Konstanten
        zu einer Warnung und wurden als Zeichenketten interpretiert.
       
- 
        Wenn die falsche Anzahl von Argumenten an eine interne Funktion
        übergeben wird, die keinen Parameter mit variabler Länge hat, wird ein
        ArgumentCountError geworfen.
       
- 
        Wenn ungültige zählbare Typen an count() übergeben
        werden, wird ein TypeError geworfen.
       
 
      Einige Hinweise wurden in Warnungen umgewandelt:
      
       
       - Der Versuch, eine undefinierte Variable zu lesen.
- Der Versuch, eine undefinierte Eigenschaft zu lesen.
- Der Versuch, einen undefinierten Array-Schlüssel zu lesen.
- Der Versuch, eine Eigenschaft eines Nicht-Objekts zu lesen.
- 
        Der Versuch, auf einen Array-Index eines Nicht-Arrays zuzugreifen.
       
- Der Versuch, ein Array in eine Zeichenkette zu konvertieren.
- Der Versuch, eine Ressource als Array-Schlüssel zu verwenden.
- 
        Der Versuch, null, einen Boolean oder einen Float als
        Zeichenketten-Offset zu verwenden.
       
- 
        Der Versuch, einen Zeichenketten-Offset zu lesen, der außerhalb des
        zulässigen Bereichs liegt.
       
- 
        Der Versuch, einem Zeichenketten-Offset eine leere Zeichenkette
        zuzuweisen.
       
 
- 
     
      Der Versuch, einem Zeichenketten-Offset mehrere Bytes zuzuweisen, führt
      nun zu einer Warnung.
      
- 
     
      Unerwartete Zeichen in Quelldateien (z. B. NUL-Bytes außerhalb von
      Zeichenketten) führen nun statt zu einer Warnung beim Kompilieren zu
      einer ParseError-Exception.
      
- 
     
      Nicht abgefangene Exceptions durchlaufen nun einen "sauberen Shutdown",
      was bedeutet, dass nach einer nicht abgefangenen Exception die
      Destruktoren aufgerufen werden.
      
- 
     
      Der bei der Kompilierung auftretende schwere Fehler "Only variables can
      be passed by reference" wurde in die Laufzeit verschoben und in die
      Error-Exception "Argument cannot be passed by
      reference" umgewandelt.
      
- 
     
      Einige "Only variables should be passed by reference"-Hinweise wurden
      in die Exception "Argument cannot be passed by reference" umgewandelt.
      
- 
     
      Der für anonyme Klassen erzeugte Name hat sich geändert. Er enthält nun
      den Namen des ersten Elternteils oder der ersten Schnittstelle:
      
       
<?php
 new class extends ParentClass {};
 // -> ParentClass@anonymous
 new class implements FirstInterface, SecondInterface {};
 // -> FirstInterface@anonymous
 new class {};
 // -> class@anonymous
 ?>
 
 
      Auf den oben gezeigten Namen folgen noch ein NUL-Byte und ein
      eindeutiges Suffix.
      
- 
     
      Verweise auf nicht-absolute Trait-Methoden in Anpassungen von
      Trait-Aliasen müssen nun eindeutig sein:
      
       
<?php
 class X {
 use T1, T2 {
 func as otherFunc;
 }
 function func() {}
 }
 ?>
 
 
      Wenn sowohl T1::func()als auchT2::func()existieren, wurde dieser Code bisher stillschweigend akzeptiert, und es
      wurde angenommen, dass func sich aufT1::funcbezieht. Nun
      erzeugt er stattdessen einen schweren Fehler und es muss explizit
      entwederT1::funcoderT2::funcgeschrieben
      werden.
 
- 
     
      Die Signatur von abstrakten Methoden, die in Traits definiert sind, wird
      nun anhand der Methode der implementierenden Klasse überprüft:
      
       
<?php
 trait MyTrait {
 abstract private function neededByTrait(): string;
 }
 
 class MyClass {
 use MyTrait;
 
 // Fehler, da der Rückgabetyp nicht übereinstimmt.
 private function neededByTrait(): int { return 42; }
 }
 ?>
 
 
- 
     
      Deaktivierte Funktionen werden nun genauso behandelt wie nicht
      existierende Funktionen. Wenn eine deaktivierte Funktion aufgerufen
      wird, wird sie als unbekannt gemeldet, und es ist nun möglich, eine
      deaktivierte Funktion neu zu definieren.
      
- 
     
      data://-Stream-Wrapper sind nicht mehr beschreibbar,
      was dem dokumentierten Verhalten entspricht.
 
- 
     
      Die arithmetischen und bitweisen Operatoren +,-,*,/,**,%,<<,>>,&,|,^,~,++und--lösen nun ausnahmslos einen TypeError aus, wenn
      einer der der Operanden ein Array, eine Ressource oder ein nicht
      überladenes Objekt ist. Die einzige Ausnahme hiervon ist die
      Array-Zusammenführung Array+Array, die weiterhin
      unterstützt wird.
 
- 
     
      Die Umwandlung vom Typ Float in den Typ String erfolgt nun immer
      unabhängig von der Locale.
      
       
<?php
 setlocale(LC_ALL, "de_DE");
 $f = 3.14;
 echo $f, "\n";
 // Vorher: 3,14
 // Jetzt:  3.14
 ?>
 
 
      Siehe printf(), number_format()
      und NumberFormatter() für Möglichkeiten, die
      Formatierung von Zahlen anzupassen.
      
      
- 
     
      Die Unterstützung für die veraltete Verwendung von geschweiften Klammern
      für den Offset-Zugriff wurde entfernt.
      
       
<?php
 // Anstelle von:
 $array{0};
 $array{"key"};
 // schreiben Sie:
 $array[0];
 $array["key"];
 ?>
 
 
- 
     
      Wenn der final-Modifikator auf eine private Methode angewendet wird,
      wird nun eine Warnung erzeugt, es sei denn, die Methode ist der
      Konstruktor.
      
      
- 
     
      Wenn im Konstruktor eines Objekts exit() aufgerufen
      wird, wird der Destruktor des Objekts nicht mehr aufgerufen. Dies
      entspricht dem Verhalten, wenn ein Konstruktor eine Exception auslöst.
      
- 
     
      Namen mit Bezug auf einen Namensraum dürfen keine Leerzeichen mehr
      enthalten: Während Foo\Barals Namensraum-Name erkannt
      wird, wirdFoo \ Barnicht erkannt. Umgekehrt sind
      reservierte Schlüsselwörter nun als Namensraumsegmente erlaubt, was auch
      die Interpretation des Codes verändern kann:new\xist nun
      gleichbedeutend mitconstant('new\x'), nicht mitnew \x().
 
- 
     
      Verschachtelte ternäre Ausdrücke müssen nun explizit in Klammern gesetzt
      werden.
      
      
- 
     
      Die Funktionen debug_backtrace() und
      Exception::getTrace() referenzieren nun keine
      Parameter mehr. Es ist nicht mehr möglich, über einen Backtrace die
      Parameter einer Funktion zu ändern.
      
- 
     
      Die Handhabung numerischer Zeichenketten wurde geändert, damit sie
      intuitiver und weniger fehleranfällig ist. Nachfolgende Leerzeichen sind
      nun in numerischen Zeichenketten erlaubt, um mit der Behandlung von
      führenden Leerzeichen übereinzustimmen. Dies betrifft hauptsächlich:
      
       
       - Die Funktion is_numeric()
- Vergleiche zwischen Zeichenketten
- Typdeklarationen
- Inkrement- und Dekrement-Operationen
 
      Das Konzept einer "vorangestellten numerischen Zeichenkette" wurde
      größtenteils aufgegeben; die Fälle, in denen dies beibehalten wird,
      dienen dazu, die Umstellung zu erleichtern. Zeichenketten, die eine
      E_NOTICE"A non well-formed numeric value
      encountered" ausgaben, geben nun eineE_WARNING"A
      non-numeric value encountered" aus, und alle Zeichenketten, die eineE_WARNING"A non-numeric value encountered"
      ausgaben, lösen nun einen TypeError aus. Dies
      betrifft vor allem:
 
       
       - Arithmetische Operationen
- Bitweise Operationen
 
      Diese Änderung von E_WARNINGzu
      TypeError betrifft auch dieE_WARNING"Illegal string offset 'string'" für
      unzulässige Zeichenketten-Offsets. Das Verhalten von expliziten
      Umwandlungen von Zeichenketten in int/float hat sich nicht geändert.
 
- 
     
      Magische Methoden werden nun auf ihre Parameter und Rückgabetypen
      geprüft, falls sie diese deklariert haben. Die Signaturen sollten der
      folgenden Liste entsprechen:
      
       
       - __call(string $name, array $arguments): mixed
- __callStatic(string $name, array $arguments): mixed
- __clone(): void
- __debugInfo(): ?array
- __get(string $name): mixed
- __invoke(mixed $arguments): mixed
- __isset(string $name): bool
- __serialize(): array
- __set(string $name, mixed $value): void
- __set_state(array $properties): object
- __sleep(): array
- __unserialize(array $data): void
- __unset(string $name): void
- __wakeup(): void
 
- 
     
      Array-Schlüssel, die an die Funktion
      call_user_func_array() übergeben werden, werden nun
      als Namen der Parameter interpretiert. In früheren Versionen wurden sie
      stillschweigend ignoriert.
      
- 
     
      Die Deklaration einer Funktion namens assert()innerhalb eines Namensraums ist nicht mehr erlaubt und erzeugt einenE_COMPILE_ERROR. Die Funktion
      assert() unterliegt einer speziellen Verarbeitung
      durch die Engine, was zu einem inkonsistenten Verhalten führen kann,
      wenn eine Funktion mit demselben Namen innerhalb eines Namensraums
      definiert wird.