PHP 8.4.1 Released!

Nicht abwärtskompatible Änderungen

Übergabe von zu wenig Funktionsparametern löst Fehler aus

Bisher wurde eine Warnung ausgegeben, wenn eine benutzerdefinierte Funktion mit zu wenig Parametern aufgerufen wurde, nun wird statt einer Warnung eine Error-Exception ausgelöst. Diese Änderung gilt nur für benutzerdefinierte Funktionen und wirkt sich nicht auf interne Funktionen aus:

<?php
function test($param){}
test();

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Verbot dynamischer Aufrufe von Funktionen, die Geltungsbereiche untersuchen

Bei bestimten Funktionen sind dynamische Aufrufe (in der Form $func() oder array_map('extract', ...) usw.) nicht mehr zulässig. Dies gilt für Funktionen, die einen anderen Bereich prüfen oder ändern und dadurch ein mehrdeutiges und undefiniertes Verhalten verursachen. Von dieser Änderung sind folgende Funktionen betroffen:

<?php
(function () {
$func = 'func_num_args';
$func();
})();

Das oben gezeigte Beispiel erzeugt folgende Ausgabe:

Warning: Cannot call func_num_args() dynamically in %s on line %d

Ungültige Namen für Klassen, Schnittstellen und Traits

Die folgenden Bezeichnungen können nicht als Namen für Klassen, Schnittstellen oder Traits verwendet werden:

Umwandlung numerischer Zeichenketten berücksichtigt wissenschaftliche Notation

Ganzzahlige Operationen und Umwandlungen berücksichtigen bei numerischen Zeichenketten nun die wissenschaftliche Notation. Dies beinhaltet auch die Umwandlung per (int) und die folgenden Funktionen: intval() (mit Basis 10), settype(), decbin(), decoct() und dechex().

Korrekturen beim Algorithmus von mt_rand()

Die Funktion mt_rand() verwendet nun standardmäßig die korrigierte Version des Mersenne-Twister-Algorithmus. Bei Code, der sich auf die deterministische Ausgabe von mt_rand() verlässt, kann mt_srand() mit der Konstante MT_RAND_PHP als zweitem, optionalem Parameter verwendet werden, um das alte (fehlerhafte) Verhalten zu wiederherzustellen.

rand() und mt_rand() werden zu Aliasen für srand() bzw. mt_srand()

Die Funktionen rand() und srand() sind nun Aliase für mt_rand() bzw. mt_srand(). Das bedeutet, dass sich die Ausgabe der folgenden Funktionen geändert hat: rand(), shuffle(), str_shuffle() und array_rand().

Das ASCII-Steuerzeichen Delete darf nicht in Bezeichnern verwendet werden

Das ASCII-Steuerzeichen Delete (0x7F) darf nicht mehr in Bezeichnern verwendet werden, die nicht in Anführungszeichen stehen.

Änderungen bei syslog als error_log

Wenn die INI-Einstellung error_log auf syslog gesetzt ist, werden die PHP-Fehlerstufen den entsprechenden Fehlerstufen von syslog zugeordnet. Dies führt im Vergleich zum vorherigen Ansatz, bei dem alle Fehler nur auf der Ebene der Benachrichtigung protokolliert wurden, zu einer feineren Differenzierung in den Fehlerprotokollen.

Destruktoren werden bei unvollständigen Objekten nicht aufgerufen

Für ein Objekt, das während der Ausführung seines Konstruktors eine Ausnahme auslöst, wird nun kein Destruktor mehr aufgerufen. Zuvor hing dieses Verhalten davon ab, ob das Objekt außerhalb des Konstruktors referenziert wurde (z. B. durch ein Exception-Backtrace).

Behandlung von per Referenz übegebenen Parametern durch call_user_func()

Die Funktion call_user_func() erzeugt nun immer eine Warnung, wenn sie für Funktionen aufgerufen wird, die Parameter per Referenz entgegennimmt. Vorher hing das Verhalten davon ab, ob der Aufruf vollständig definiert war oder nicht.

Außerdem unterbrechen call_user_func() und call_user_func_array() den Funktionsaufruf in diesem Fall nicht mehr. Es wird zwar die Warnung "expected reference" ausgegeben, aber der Aufruf wird wie gewohnt fortgesetzt.

Der leere Indexoperator ist nicht mehr auf Zeichenketten anwendbar

Die Anwendung des leeren Indexoperators auf eine Zeichenkette (z. B. $str[] = $x) führt zu einem fatalen Fehler. In früheren Versionen wurde die Zeichenkette stattdessen stillschweigend in ein Array umgewandelt.

Zuweisen eines Wertes an eine leere Zeichenkette über den Index der Zeichenkette

Eine Zeichenkette kann nun genauso verändert werden wie eine nicht-leere, d. h., wenn in einen Offset außerhalb der Zeichenkette geschrieben werden soll, wird dieser mit Leerzeichen aufgefüllt. Dabei werden nicht-ganzzahlige Typen in Integer umgewandelt und nur das erste Zeichen der zugewiesenen Zeichenkette wird verwendet. Zuvor wurden leere Zeichenketten stillschweigend wie ein leeres Array behandelt.

<?php
$a
= '';
$a[10] = 'foo';
var_dump($a);
?>

Das oben gezeigte Beispiel erzeugt mit PHP 7.0 folgende Ausgabe:

array(1) {
  [10]=>
  string(3) "foo"
}

Das oben gezeigte Beispiel erzeugt mit PHP 7.1 folgende Ausgabe:

string(11) "          f"

Entfernte INI-Direktiven

Die folgenden INI-Direktiven wurden entfernt:

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

Die Reihenfolge der Array-Elemente, die automatisch durch Referenzzuweisung erstellt werden, wurde geändert

Die Reihenfolge der Elemente, die in einem Array durch Zuweisung per Referenz automatisch erstellt wurden, hat sich geändert. Zum Beispiel:

<?php
$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Das oben gezeigte Beispiel erzeugt mit PHP 7.0 folgende Ausgabe:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Das oben gezeigte Beispiel erzeugt mit PHP 7.1 folgende Ausgabe:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Sortierreihenfolge gleichwertiger Elemente

Aufgrund von Verbesserungen des internen Sortieralgorithmus kann sich die Sortierreihenfolge von Elementen, die beim Vergleich als gleichwertig betrachtet werden, im Vergleich zu vorherigen Versionen ändern.

Hinweis:

Es wird davon abgeraten, sich auf die Reihenfolge der Elemente, die als gleichwertig betrachtet werden, zu verlassen; sie kann sich jederzeit ändern.

Fehlermeldung für Fehler der Stufe E_RECOVERABLE

Die Fehlermeldung für Fehler der Stufe E_RECOVERABLE wurde von "Catchable fatal error" auf "Recoverable fatal error" geändert.

Der Parameter $options der Funktion unserialize()

Bei der Funktion unserialize() ist das Element allowed_classes des Parameters $options nun streng typisiert, d. h., wenn etwas anderes als ein Array oder ein Bool angegeben wird, gibt unserialize() false zurück und löst einen Fehler der Stufe E_WARNING aus.

Der Konstruktor der Klasse DateTime enthält nun Mikrosekunden

Die Klassen DateTime und DateTimeImmutable integrieren nun Mikrosekunden in korrekter Weise, wenn sie aus der aktuellen Zeit konstruiert werden, entweder explizit oder mit einer relativen Zeichenkette (z. B. "first day of next month"). Das bedeutet, dass einfache Vergleiche zweier neu erstellter Instanzen nun eher false zurückgeben als true:

<?php
new DateTime() == new DateTime();
?>

Umwandlungen fataler Fehler in Error-Exceptions

Wenn in der Erweiterung Date die serialisierten Daten für die Klassen DateTime oder DatePeriod nicht korrekt sind oder bei der Initialisierung der Zeitzone anhand der serialisierten Daten ein Fehler auftritt, wird von den Methoden __wakeup() oder __set_state() nun eine Error-Exception ausgelöst, statt einen fatalen Fehler zu verursachen.

In der Erweiterung DBA lösen Funktionen, mit denen Daten geändert werden können (z. B. dba_insert()) nun eine Error-Exception aus, statt einen abfangbaren fatalen Fehler zu verursachen, wenn der Schlüssel nicht genau zwei Elemente enthält.

In der Erweiterung DOM lösen ungültige Schema- oder RelaxNG-Validierungskontexte nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen. Auch der Versuch, eine Knotenklasse zu registrieren, die nicht die entsprechende Basisklasse erweitert oder der Versuch, eine ungültige Eigenschaft zu lesen oder eine schreibgeschützte Eigenschaft zu überschreiben, lösen nun ebenfalls eine Error-Exception aus.

In der Erweiterung IMAP lösen E-Mail-Adressen, die größer als 16385 Bytes sind, nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen.

Wenn in der Erweiterung Intl in einer Klasse, die die Klasse Collator erweitert, der übergeordnete Konstruktor nicht aufgerufen wird, bevor die übergeordneten Methoden aufgerufen werden, wird nun ein Error ausgelöst, statt einen wiederherstellbaren fatalen Fehler zu verursachen. Auch das Klonen eines Transliterator-Objekts löst nun eine Error-Exception aus, wenn das Klonen des internen Transliterators fehlschlägt, statt einen fatalen Fehler zu verursachen.

Wenn in der Funktion ldap_batch_modify() der Erweiterung LDAP ein unbekannter Änderungstyp angegeben wird, wird nun eine Error-Exception ausgelöst, statt einen fatalen Fehler zu verursachen.

In der Erweiterung mbstring lösen die Funktionen mb_ereg() und mb_eregi() nun eine ParseError-Exception aus, wenn ein ungültiger PHP-Ausdruck angegeben wird und wenn die Option 'e' verwendet wird.

In der Erweiterung Mcrypt lösen die Funktionen mcrypt_encrypt() und mcrypt_decrypt() nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen, wenn mcrypt nicht initialisiert werden kann.

Wenn in der Erweiterung mysqli versucht wird, eine ungültige Eigenschaft zu lesen oder eine schreibgeschützte Eigenschaft zu überschreiben, wird nun eine Error-Exception ausgelöst, statt einen fatalen Fehler zu verursachen.

Wenn in der Erweiterung Reflection ein Reflection-Objekt oder eine Objekteigenschaft nicht abgerufen werden kann, wird nun eine Error-Exception ausgelöst, statt einen fatalen Fehler zu verursachen.

In der Erweiterung Session löst ein benutzerdefinierter Session-Handler, der keine Zeichenkette für die Session-ID zurückgibt, nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen, wenn eine Funktion aufgerufen wird, die eine Sesion-ID erzeugen muss.

In der Erweiterung SimpleXML löst das Erstellen eines unbenannten oder doppelten Attributs nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen.

In der Erweiterung SPL löst der Versuch, ein SplDirectory-Objekt zu klonen, nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen. Auch der Aufruf der Methode ArrayIterator::append() während über ein Objekt iteriert wird, löst nun eine Error-Exception aus.

In der Standarderweiterung löst die Funktion assert() nun eine ParseError-Exception aus, statt einen abfangbaren fatalen Fehler zu verursachen, wenn ihr als erster Parameter eine Zeichenkette mit ungültigem PHP-Code übergeben wird. Auch der Aufruf der Funktion forward_static_call() außerhalb eines Klassenbereichs löst nun eine Error-Exception aus.

Wenn in der Erweiterung Tidy versucht wird, einen tidyNode manuell zu erstellen, wird nun eine Error-Exception ausgelöst, statt einen fatalen Fehler zu verursachen.

In der Erweiterung WDDX löst eine zirkuläre Referenz bei der Serialisierung nun eine eine Error-Exception aus, statt einen fatalen Fehler zu verursachen.

In der Erweiterung XML-RPC löst eine zirkuläre Referenz bei der Serialisierung nun eine eine Error-Exception aus, statt einen fatalen Fehler zu verursachen.

In der Erweiterung Zip löst die Methode ZipArchive::addGlob() nun eine Error-Exception aus, statt einen fatalen Fehler zu verursachen, wenn Glob nicht unterstützt wird.

Lexikalisch gebundene Variablen können Namen nicht mehrfach verwenden

Variablen, die über das use-Konstrukt an eine Closure gebunden sind, können weder $this noch den Namen irgendwelcher superglobals oder Parameter verwenden. Die folgenden Funktionsdefinitionen führen zum Beispiel alle zu einem fatalen Fehler:

<?php
$f
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

Änderung des Parametertyps bei long2ip()

Die Funktion long2ip() erwartet nun einen Parameter vom Typ int statt vom Typ string.

JSON-Kodierung und -Dekodierung

Die INI-Einstellung serialize_precision steuert nun die Genauigkeit der Serialisierung bei der Kodierung von Floats (Gleitkommazahlen).

Die Dekodierung eines leeren Schlüssels führt nun zu einem leeren Eigenschaftsnamen anstelle von _empty_.

<?php
var_dump
(json_decode(json_encode(['' => 1])));

Das oben gezeigte Beispiel erzeugt eine ähnliche Ausgabe wie:

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

Wenn das Flag JSON_UNESCAPED_UNICODE an die Funktion json_encode() übergeben wird, werden nun die Sequenzen U+2028 und U+2029 maskiert.

Änderungen der Semantik der Parameter bei mb_ereg() und mb_eregi()

Der dritte Parameter der Funktionen mb_ereg() und mb_eregi() (regs) wird nun auf ein leeres Array gesetzt, wenn es keine Übereinstimmung gab. Zuvor wurde der Parameter nicht geändert.

Unterstützung für sslv2-Streams entfernt

Der sslv2-Stream wurde nun aus OpenSSL entfernt.

Verbot von "return;" für typisierte Rückgaben bereits bei der Kompilierung

In einer Funktion, die einen Rückgabetyp deklariert, löst eine return-Anweisung ohne Argument nun einen E_COMPILE_ERROR aus (außer der Rückgabetyp ist als void deklariert), auch wenn die return-Anweisung nie erreicht wird.

add a note

User Contributed Notes 5 notes

up
46
love at sickpeople dot se
7 years ago
For anyone migrating from 5.x to 7.1:

About "Array ordering when elements are automatically created during by reference assignments has changed" on this page

(http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

The behaviour of 7.1 is THE SAME as of PHP 5. It is only 7.0 that differs.

See https://3v4l.org/frbUc

<?php

$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
up
34
kees at twekaers dot net
7 years ago
The backwards incompatible change 'The empty index operator is not supported for strings anymore' has a lot more implications than just a fatal error on the following code

<?php
$a
= "";
$a[] = "hello world";
var_dump($a);
?>

This will give a fatal error in 7.1 but will work as expected in 7.0 or below and give you: (no notice, no warning)

array(1) {
[0]=>
string(11) "hello world"
}

However, the following is also changed:

<?php
$a
= "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) " h"
// pre-7.1: array(1) { [0]=> string(11) "hello world" }

?>
up
17
m dot r dot sopacua at gmail dot com
7 years ago
"OMFG! Why was session.hash_function removed?!? Dude!"

https://wiki.php.net/rfc/session-id-without-hashing

There. Saved ya a search.
up
2
mikem at gmail dot com
6 years ago
ArgumentCountError - this modification is the main reason to avoid this version on older projects.
up
0
david at artefactual dot com
5 years ago
Regarding the ArgumentCountError, PHP 7.1+ does still support user functions with a variable number of arguments, using the "func(...$args) {}" syntax, see: https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list
To Top