## Changements non rétrocompatibles

Sauf mention contraire dans cette section, chaque nouvelle » fonction, » classe, interface, énumération, ou » constante peut entraîner le lancement d'une exception de redéclaration Error.

### PHP Core

#### Changement du comportement de exit()

Les constructions de langage exit() (et die()) se comportent désormais davantage comme une fonction. Cela signifie qu'elles peuvent maintenant être passées comme des callables, sont affectées par l'instruction `strict_types`, et effectuent désormais les coercitions de type habituelles au lieu de caster toute valeur non entière en chaîne.

En conséquence, passer des types invalides à exit() et die() entraîne désormais systématiquement le lancement d'une exception TypeError.

#### Récursion lors de la comparaison

Rencontrer une récursion lors de la comparaison entraîne désormais une exception Error au lieu d'une erreur fatale `E_ERROR`.

#### Modification indirecte de propriétés en lecture seule

La modification indirecte de propriétés en lecture seule dans `__clone()` n'est plus autorisée, par exemple `$ref = &$this->readonly`. C'était déjà interdit pour l'initialisation en lecture seule, et c'était un oubli dans l'implémentation de la "réinitialisation en lecture seule lors du clonage".

#### Changement de type des constantes

Les constantes `PHP_DEBUG` et `PHP_ZTS` sont désormais de type bool. Auparavant, elles étaient de type int.

#### Longueur du nom de fichier temporaire

Le nom des fichiers téléversés et des fichiers créés par la fonction tempnam() est désormais plus long de 13 octets. La longueur totale dépend toujours de la plateforme.

#### Suppression du niveau d'erreur `E_STRICT`

Le niveau d'erreur `E_STRICT` a été supprimé, car il n'était plus utilisé dans le moteur PHP. La constante `E_STRICT` a également été déprécié.

### Constantes de classe d'extension désormais typées

Les constantes de classe suivantes déclarent désormais un type sur leurs constantes :

- Date
- Intl
- PDO
- Reflection
- SPL
- Sqlite
- XMLReader

### Migration des ressources vers des objets

Plusieurs resources ont été migrés vers des objets. La vérification de la valeur de retour à l'aide de is_resource() doit être remplacée par des vérifications de `false`, sauf indication contraire.

#### DBA

Les fonctions DBA acceptent et retournent désormais Dba\Connection à la place de resources `dba_connection`.

#### ODBC

Les fonctions ODBC acceptent et retournent désormais Odbc\Result à la place de resources `odbc_result`.

Les fonctions ODBC acceptent et retournent désormais Odbc\Connection à la place de resources `odbc_connection`.

#### SOAP

La propriété SoapClient::$httpurl est désormais un objet Soap\Url plutôt qu'une resource `soap_url`. Les vérifications à l'aide de is_resource() (par exemple `is_resource($client->httpurl)`) doivent être remplacées par des vérifications de `null` (par exemple `$client->httpurl !== null`).

La propriété SoapClient::$sdl est désormais un objet Soap\Sdl plutôt qu'une resource `soap_sdl`. Les vérifications à l'aide de is_resource() (par exemple `is_resource($client->sdl)`) doivent être remplacées par des vérifications de `null` (par exemple `$client->sdl !== null`).

### Nouvelles alertes et exceptions

De nouvelles alertes et exceptions ont été ajoutées pour signaler des erreurs de programmation, c'est-à-dire des valeurs invalides fournies en argument.

#### Curl

curl_multi_select() lance désormais une ValueError si le paramètre `timeout` est inférieur à `0` ou supérieur à `PHP_INT_MAX`.

#### Gd

imagejpeg(), imagewebp(), imagepng(), imageavif() lancent désormais une ValueError si un `quality` invalide est passé.

imageavif() lance désormais une ValueError si un paramètre `speed` invalide est passé.

imagescale() lance désormais une ValueError si les paramètres `width` ou `height` sont en dehors des limites.

imagescale() lance désormais une ValueError si une valeur de `mode` invalide est passée.

imagefilter() lance désormais une ValueError avec le filtre `IMG_FILTER_SCATTER` si les paramètres `sub` ou `plus` sont en dehors des limites.

#### Gettext

bind_textdomain_codeset(), textdomain(), d()*gettext() lance désormais une ValueError si un `domain` invalide est passé.

#### Intl

resourcebundle_get(), ResourceBundle::get(), et l'accès aux indices sur un ResourceBundle lancent désormais :

- TypeError pour les types d'offset invalides
- ValueError pour une chaîne de caractères vide
- ValueError si l'index entier ne rentre pas dans un entier signé 32 bits

IntlDateFormatter::__construct() lance une ValueError si le `locale` est invalide.

NumberFormatter::__construct() lance une ValueError si le `locale` est invalide.

#### MBString

mb_encode_numericentity() et mb_decode_numericentity() vérifient désormais que `map` est uniquement composé de entiers, si ce n'est pas le cas, une ValueError est

mb_http_input() lance désormais une ValueError si le `type` est invalide.

mb_http_output() vérifie désormais que `encoding` ne contient pas de caractères nuls, si c'est le cas, une ValueError est lancée.

#### ODBC

odbc_fetch_row() retourne `false` lorsque `row` est inférieur ou égal à `0`. Une alerte est désormais émise dans ce cas.

#### PCNTL

Les fonctions pcntl_sigprocmask(), pcntl_sigwaitinfo(), et pcntl_sigtimedwait() lancent désormais :

- Une ValueError si le tableau `signals` est vide (sauf pour pcntl_sigprocmask() si le `mode` est `SIG_SETMASK`)
- Une TypeError si une valeur du tableau `signals` n'est pas un entier
- Une ValueError si la valeur du `signals` n'est pas un numéro de signal valide

La fonction pcntl_sigprocmask() lance désormais une ValueError si le `mode` n'est pas l'une des `SIG_BLOCK`, `SIG_UNBLOCK`, ou `SIG_SETMASK`.

La fonction pcntl_sigtimedwait() lance désormais :

- Une ValueError si `seconds` est inférieur à `0`
- Une ValueError si `nanoseconds` est inférieur à `0` ou supérieur à `1e9`
- Une ValueError si les deux `seconds` et `nanoseconds` sont `0`

#### Session

Définir une valeur non positive pour session.gc_divisor ou une valeur négative pour session.gc_probability émet désormais une alerte.

#### SimpleXML

Appeler simplexml_import_dom() avec un objet non-XML lance désormais une TypeError au lieu d'une ValueError.

#### Standard

La fonction round() vérifie désormais la valeur du `mode` et lance une ValueError pour les modes invalides. Auparavant, les modes invalides auraient été interprétés comme `PHP_ROUND_HALF_UP`.

La fonction str_getcsv() lance désormais une ValueError si les arguments `separator` et `enclosure` ne font pas un octet de long, ou si l'argument `escape` n'est pas un octet de long ou une chaîne vide. Cela aligne le comportement pour être identique à celui de fputcsv() et fgetcsv().

La fonction php_uname() lance désormais une ValueError si le `mode` est invalide.

L'option `"allowed_classes"` pour unserialize() lance désormais des TypeError et ValueError si ce n'est pas un array de noms de classe.

#### XMLReader

Passer un encodage de caractères invalide à XMLReader::open() ou XMLReader::XML() lance désormais une ValueError.

Passer une chaîne de caractères contenant des octets émettait précédemment une alerte et lance désormais une ValueError.

#### XMLWriter

Passer une chaîne de caractères contenant des octets émettait précédemment une alerte et lance désormais une ValueError.

#### XSL

XSLTProcessor::setParameter() lance désormais une ValueError lorsque ses arguments contiennent des octets nuls. Cela n'a jamais fonctionné correctement en premier lieu, c'est pourquoi une exception est maintenant lancée.

Appeler XSLTProcessor::importStyleSheet() avec un objet non-XML lance désormais une TypeError au lieu d'une ValueError.

L'échec d'appeler une fonction de rappel PHP pendant l'évaluation lance au lieu d'émettre une alerte.

### Date

Le symbole `number` dans les formats relatifs accepte à nouveau plusieurs signes, par exemple `+-2`. `number` symbols in relative formats

### DOM

Quelques méthodes DOM retournaient précédemment `false` ou une DOMException `PHP_ERR` si un nouveau nœud ne pouvait pas être alloué. Elles lancent désormais systématiquement une DOMException `INVALID_STATE_ERR`. Cette situation est extrêmement improbable et la probabilité d'être affecté est faible. En conséquence, DOMImplementation::createDocument() a désormais un type de retour provisoire de DOMDocument à la place de `DOMDocument|false`.

Auparavant, les objets DOMXPath pouvaient être clonés, mais en résultaient en un objet inutilisable. Cela n'est plus possible, et cloner un objet DOMXPath lance désormais une Error.

La méthode DOMImplementation::getFeature() a été supprimée.

### GMP

La classe GMP est désormais finale et ne peut plus être étendue.

### MBString

En cas de chaines invalides (celles avec des erreurs d'encodage), mb_substr() interprète désormais les indices de caractères de la même manière que la plupart des autres fonctions mbstring. Cela signifie que les indices de caractères retournés par mb_strpos() peuvent être passés à mb_substr().

Pour les chaines SJIS-Mac (MacJapanese), les indices de caractères passés à mb_substr() font désormais référence aux indices des points de code Unicode qui sont produits lorsque la chaine est convertie en Unicode. C'est significatif car environ 40 caractères SJIS-Mac se convertissent en une séquence de plusieurs points de code Unicode.

### MySQLi

La constante non utilisée et non documentée `MYSQLI_SET_CHARSET_DIR` a été supprimée.

La constante `MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH` a été supprimée. Cette fonctionnalité n'est pas disponible avec mysqlnd.

Les constantes `MYSQLI_STMT_ATTR_CURSOR_TYPE` et `MYSQLI_STMT_ATTR_PREFETCH_ROWS` ont été supprimées. Ces fonctionnalités n'ont jamais été implémentées, ni avec mysqlnd ni avec libmysql.

La constante non utilisée `MYSQLI_TYPE_INTERVAL`, qui est actuellement un stub et un alias pour `MYSQLI_TYPE_ENUM`, a été supprimée.

### MySQLnd

Le code d'erreur signalé pour les délais d'attente du serveur MySQL a été de `2006` à `4031` pour les versions du serveur Mysql 8.0.24 et supérieures.

### Opcache

La valeur maximale de la configuration opcache.interned_strings_buffer sur les architectures 64 bits est désormais `32767`. Auparavant, elle était de `4095`.

#### JIT

La valeur par défaut de la configuration JIT a changé de `opcache.jit=tracing` et `opcache.jit_buffer_size=0` pour `opcache.jit=disable` et `opcache.jit_buffer_size=64M`, respectivement.

Cela n'affecte pas le comportement observable par défaut, car le JIT est toujours désactivé par défaut. Cependant, il est désormais désactivé via la configuration opcache.jit, plut$ot que opcache.jit_buffer_size. Cela peut affecter les utilisateurs qui ont précédemment activé le JIT via opcache.jit_buffer_size exclusivement, sans spécifier également un mode JIT en utilisant opcache.jit. Pour activer la compilation JIT, définissez la valeur de configuration opcache.jit en conséquence.

Si la compilation JIT est activée, PHP quittera désormais avec une erreur fatale au démarrage si l'initialisation du compilateur JIT a échoué pour une raison quelconque.

### PCNTL

Les fonctions pcntl_sigprocmask(), pcntl_sigwaitinfo(), et pcntl_sigtimedwait() retournent désormais systématiquement `false` en cas d'échec. Dans certains cas précédemment, elles pouvaient retourné la valeur `-1`.

### PCRE

La version de pcre2lib incluse a été mise à jour en version 10.44. Par conséquent, cela signifie que `{,3}` est désormais reconnu comme un quantificateur au lieu d'un texte. De plus, la signification de certaines classes de caractères en mode UCP a changé. Consultez le » Journal des modifications de PCRE2 pour un journal des modifications complet.

### PDO_DBLIB

Les attributs `Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER` et `Pdo\Dblib::ATTR_DATETIME_CONVERT` agissent désormais comme des attributs booléens au lieu d'attributs entiers. Donc définir l'attribut via PDO::setAttribute() et le récupérer via PDO::getAttribute() attend et retourne un bool.

### PDO_FIREBIRD

L'attribut `PDO::ATTR_AUTOCOMMIT` agit désormais comme un attribut booléen au lieu d'un attribut entier. Donc définir l'attribut via PDO::setAttribute() et le récupérer via PDO::getAttribute() attend et retourne un bool.

L'exntension expose désormais certaines API C++ Firebird, donc la construction de cette extension nécessite désormais un compilateur C++. De plus, l'extension doit désormais être compilée contre fbclient 3.0 ou supérieur.

### PDO_MYSQL

Les attributs `PDO::ATTR_AUTOCOMMIT` `PDO::ATTR_EMULATE_PREPARES`, et `PDO::MYSQL_ATTR_DIRECT_QUERY` agissent désormais comme des attributs booléens au lieu d'attributs entiers. Donc définir l'attribut via PDO::setAttribute() et le récupérer via PDO::getAttribute() attend et retourne un bool.

### PDO_PGSQL

Les informations de connexion DSN, lorsqu'elles sont définies, ont la priorité sur les arguments du constructeur PDO, étant plus proches de ce que la documentation indique.

### SimpleXML

SimpleXMLElement n'est pas seulement une représentation d'un élément XML, mais c'est aussi un RecursiveIterator. Avant PHP 8.4.0, certaines de ses méthodes (par exemple SimpleXMLElement::asXML() ou SimpleXMLElement::getName()) et le casting de telles instances en chaîne de caractères réinitialisaient implicitement l'itérateur.

Cela pouvait entraîner des boucles infinies inattendues car l'itérateur était réinitialisé. Par exemple :

`<?php
$xmlString = "<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);
$nodes = $xml->a->b;
foreach ($nodes as $nodeData) {
echo "nodeData: " . $nodeData . "\n";
$xml = $nodes->asXml();
}`

formait une boucle infinie.

    nodeData: 1
    nodeData: 2
    nodeData: 2
    nodeData: 2
    nodeData: 2
    nodeData: 2
    nodeData: 2
    // ...

Cependant, ce comportement a été corrigé, et un SimpleXMLElement ne réinitialisera plus implicitement l'itérateur, sauf s'il est explicitement remis à zéro. Cela signifie que l'exemple précédent donnerait maintenant :

    nodeData: 1
    nodeData: 2
    nodeData: 3

### SOAP

SoapClient::$typemap est désormais un array plutôt qu'une resource. Les vérifications à l'aide de is_resource() (c'est-à-dire `is_resource($client->typemap)`) doivent être remplacées par des vérifications de `null` (c'est-à-dire `$client->typemap !== null`).

L'extension SOAP a gagné une dépendance optionnelle sur l'extension session. Si PHP est compilé sans l'extension session et avec le drapeau de configuration --enable-rtld-now activé, des erreurs de démarrage se produiront désormais si l'extension SOAP est également utilisée. Pour résoudre ce problème, n'utilisez pas rtld-now ou chargez l'extension session.

### Standard

Lors de l'utilisation de strcspn() avec `characters` étant une chaîne vide, la longueur de la chaîne est désormais retournée au lieu de s'arrêter au premier octet nul.

http_build_query() gère désormais correctement les énumérations

stream_bucket_make_writeable() et stream_bucket_new() retournent désormais une instance de StreamBucket à la place d'une instance de stdClass.

### Tidy

Les echecs dans le constructeur lancent désormais des exceptions plutôt que d'émettre des alertes et d'avoir un objet cassé.

### XML

Les fonctions xml_set_()*_handler() déclarent désormais et vérifient une signature effective de callable|string|null pour les paramètres `handler`. De plus les valeurs de type string correspondant à des noms de méthode, d'objet défini avec xml_set_object() sont désormais vérifiées pour voir si la méthode existe sur la classe de l'objet précédemment passé. Cela signifie que xml_set_object() doit maintenant toujours être appelée avant de définir des noms de méthode en tant que callable. Passer une chaîne vide pour désactiver le gestionnaire est toujours autorisé, mais déprécié.

De plus, avec xml_set_object() et le passage de chaînes non-callable est déprécié. Il est recommandé de remplacer de telles instances par un callable se référant directement à la méthode.