Changements non rétrocompatibles

PHP Core

foreach par référence après compactage d'un tableau

Les boucles foreach par référence peuvent désormais visiter des éléments précédemment ignorés après le compactage d'un tableau. Les pointeurs internes sur des éléments supprimés passent désormais à l'élément survivant suivant lors de la copie sur écriture.

Coalescence sur null et empty() sur les propriétés magiques

?? et empty() sur une propriété magique n'appellent plus __get() lorsque __isset() a matérialisé la propriété en écrivant dans la table des propriétés. La valeur fraîchement écrite est retournée directement. isset() appliqué directement à la propriété n'est pas affecté ; les formes imbriquées telles que isset($o->p['k']) suivent le même chemin que ??.

<?php
#[\AllowDynamicProperties]
class Example
{
    public function __isset(string $name): bool
    {
        $this->$name = 'from __isset()';
        return true;
    }

    public function __get(string $name): string
    {
        return 'from __get()';
    }
}

$example = new Example();
var_dump($example->foo ?? 'default');
// À partir de PHP 8.6.0 : string(14) "from __isset()"
// Avant PHP 8.6.0 : string(12) "from __get()"

Conversion en chaîne dans array_intersect()

array_intersect() avec au moins deux tableaux convertit désormais les valeurs en chaînes lors du parcours de ses entrées plutôt que pendant les comparaisons du tri. Cela peut modifier le nombre et l'ordre des avertissements de conversion et des appels à __toString(), l'exception de conversion qui est atteinte, ainsi que le résultat pour les implémentations de __toString() à état. Les types des arguments sont validés avant de vérifier la présence de tableaux vides ou de convertir les valeurs ; un argument ultérieur invalide peut donc supprimer les effets de bord de conversion des tableaux précédents. Les valeurs ne sont pas converties si l'un des tableaux d'entrée est vide.

Saut de page supprimé par défaut

Le saut de page (\f) est désormais ajouté aux caractères supprimés par défaut par trim(), rtrim() et ltrim().

<?php
var_dump(trim("\f hello \f"));
// À partir de PHP 8.6.0 : string(5) "hello"
// Avant PHP 8.6.0 : string(9) "\f hello \f"

Nouvelles erreurs pour les arguments invalides

Les fonctions suivantes lèvent désormais une ValueError lorsqu'une valeur de drapeau ou de mode invalide est passée :

Les fonctions suivantes lèvent désormais une ValueError lorsque l'argument donné contient des octets NUL :

Les fonctions suivantes lèvent désormais une ValueError pour les valeurs hors limites, au lieu de les plafonner silencieusement ou de les laisser déborder :

  • number_format(), lorsque decimals est en dehors de la plage des entiers.
  • sleep(), lorsque seconds est supérieur à UINT_MAX, ou UINT_MAX / 1000 sous Windows.
  • usleep(), lorsque microseconds est supérieur à UINT_MAX.

linkinfo() lève désormais une ValueError lorsque l'argument path est vide.

setlocale() lève désormais une ValueError lorsqu'un nom de locale contient des octets NUL, au lieu de le tronquer silencieusement. Les tableaux ne sont désormais acceptés que pour l'argument locales. Passer un tableau comme argument de locale variadique ultérieur lance désormais une TypeError. Passer des arguments de locale supplémentaires lorsque locales est un tableau lance désormais une ArgumentCountError.

Les fonctions suivantes lèvent désormais une ValueError lorsque l'argument filename contient des octets NUL :

Notice sur la conversion imprécise de nombres

base_convert(), bindec(), hexdec() et octdec() émettent désormais une notice lorsqu'elles ne peuvent pas convertir précisément le nombre donné.

Modificateurs d'endianness dans les noms de format de unpack()

unpack() interprète désormais un < ou un > suivant immédiatement un code de format comme un modificateur d'endianness, et non comme le premier caractère du nom de l'élément. Les formats tels que "s<value" produisent désormais la clé "value" au lieu de "<value", et "C>name" lève une ValueError car le code de format C n'accepte aucun modificateur d'endianness. Un nom commençant par ces caractères n'est pas affecté lorsqu'un répéteur le précède, comme dans "s1<value". Voir aussi les nouveaux modificateurs d'endianness.

<?php
var_dump(unpack('s<value', "\x01\x00"));
// À partir de PHP 8.6.0 : ["value" => 1]
// Avant PHP 8.6.0 : ["<value" => 1]

COM

Il n'est plus possible de cloner des objets variant, car le comportement du clonage était mal défini.

cURL

La fonction de rappel enregistrée avec CURLOPT_READFUNCTION lance désormais une ValueError lorsqu'elle retourne un entier autre que 0, CURL_READFUNC_ABORT ou CURL_READFUNC_PAUSE.

DOM

Les propriétés précédemment documentées comme en lecture seule (par ex. DOMNode::$nodeType, DOMDocument::$xmlEncoding, DOMEntity::$actualEncoding, DOMEntity::$encoding, DOMEntity::$version) sont désormais déclarées avec une visibilité asymétrique (public private(set)). Toute tentative d'écriture depuis l'extérieur de la classe lève désormais Cannot modify private(set) property class::$prop from global scope au lieu de l'ancienne erreur de modification d'une propriété en lecture seule. ReflectionProperty::isWritable() rapporte également ces propriétés avec exactitude.

L'accès par index sur les objets Dom\DtdNamedNodeMap retourne désormais null pour les index entiers négatifs au lieu de retourner le premier nœud, et lève une ValueError lorsque l'index entier est supérieur à PHP_INT_MAX au lieu de déborder vers un index plus petit.

FTP

ftp_nb_fget(), ftp_nb_fput(), ftp_nb_get() et ftp_nb_put() lancent désormais une Error lorsque la connexion est déjà en cours de transfert, au lieu d'émettre un avertissement et de retourner false. ftp_close() lance déjà une exception dans la même situation.

GD

imagesetstyle(), imagefilter() et imagecrop() filtrent les types et les valeurs de leurs arguments de type tableau et lèvent en conséquence une TypeError ou une ValueError.

imageaffinematrixget() impose désormais le type array|float documenté pour le paramètre options, y compris le comportement correspondant du typage faible et strict.

GMP

gmp_fact() lève désormais une ValueError si num ne tient pas dans un unsigned long.

gmp_pow(), gmp_binomial(), gmp_root() et gmp_rootrem() lèvent désormais une ValueError si leur second argument ne tient pas dans un unsigned long.

Les opérateurs de décalage (<<, >>) et d'exponentiation (**) sur les objets GMP lèvent désormais une ValueError lorsque les opérandes de droite GMP sont en dehors de la plage des unsigned long, au lieu de les tronquer silencieusement.

L'analyse des chaînes d'entiers GMP lève désormais une ValueError pour les chaînes contenant des octets NUL, au lieu de les tronquer silencieusement.

Le message de la DivisionByZeroError levée par gmp_powm() lors d'un modulo par zéro inclut désormais le nom de la fonction et l'index de l'argument (modulus).

Intl

Passer un objet non stringable comme fuseau horaire aux API Intl qui acceptent des objets ou des chaînes de fuseau horaire lève désormais une TypeError au lieu d'une Error.

IntlIterator::current() retourne désormais null lorsqu'elle est appelée avant que l'itérateur ne soit positionné, ou après que l'itérateur est devenu invalide, au lieu d'exposer une valeur indéfinie.

IntlBreakIterator::getLocale() lève désormais une ValueError lorsque le type n'est ni Locale::ACTUAL_LOCALE ni Locale::VALID_LOCALE, au lieu de retourner false.

MessageFormatter::parse() et MessageFormatter::parseMessage() retournent désormais PHP_INT_MIN sous forme de int, plutôt que de float, sur les plateformes 64 bits lors de l'analyse de valeurs entières.

Le paramètre type de IntlBreakIterator::getPartsIterator() est passé de string à int pour correspondre à l'implémentation sous-jacente.

UConverter::transcode() rejette désormais les valeurs d'option from_subst et to_subst de plus de 127 octets, au lieu de tronquer silencieusement la longueur avant de la transmettre à ICU.

ResourceBundle::get() et resourcebundle_get() rapportent désormais les recherches de ressources sans repli avec without fallback to locale au lieu du message mal formé without fallback from to locale.

IntlDateFormatter::parse()/datefmt_parse() et IntlDateFormatter::localtime()/datefmt_localtime() lèvent désormais une TypeError lorsque l'argument offset n'est pas de type int, au lieu de convertir silencieusement la valeur.

Collator::sort(), collator_sort(), Collator::asort() et collator_asort() rapportent désormais les échecs de conversion UTF-8/UTF-16 pendant la comparaison via le mécanisme d'erreur d'intl et retournent false. Avec intl.use_exceptions activé, ces échecs lancent une IntlException. Auparavant, ces chemins émettaient un avertissement et comparaient la valeur comme une chaîne vide.

MBString

Les tables de données Unicode ont été mises à jour vers Unicode 18.0.

PCNTL

pcntl_alarm() lève désormais une ValueError si l'argument seconds est inférieur à zéro ou supérieur à la valeur UINT_MAX de la plateforme.

pcntl_exec() lève désormais une ValueError si l'argument args n'est pas un tableau de type liste.

PCRE

preg_grep() retourne désormais false au lieu d'un tableau partiel lorsqu'une erreur d'exécution PCRE se produit (par ex. une entrée UTF-8 malformée avec le modificateur u). Cela est cohérent avec les autres fonctions preg_*.

PGSQL

Lorsque pg_fetch_object() reçoit un paramètre constructor_args non vide pour une classe sans constructeur, la ValueError fait désormais référence à l'argument constructor_args au lieu de class. Les erreurs levées lorsque la classe demandée n'est pas instanciable (abstraite, interface, énumération) apparaissent désormais avant la récupération de la ligne.

Phar

Phar::mungServer() lève désormais une ValueError lorsqu'une valeur d'argument invalide est passée, au lieu de l'ignorer silencieusement.

Phar::addEmptyDir() rejette désormais les chemins "/.phar" en plus des chemins ".phar", et lève la même BadMethodCallException pour les tentatives de création du répertoire magique réservé ".phar" par cette forme. Les noms non magiques qui partagent simplement le préfixe ".phar" sont désormais traités comme des répertoires ordinaires.

Les fichiers ne sont automatiquement interprétés comme des archives Phar lors de leur inclusion que si ".phar" apparaît comme extension dans la composante nom de fichier de leur chemin. Auparavant, cela pouvait se produire dans un nom de répertoire ou comme partie d'une extension telle que ".pharma".

Session

Définir session.cookie_path, session.cookie_domain ou session.cache_limiter avec une valeur contenant des octets NUL émet désormais un avertissement et laisse le réglage inchangé. Auparavant, les octets NUL étaient silencieusement acceptés : pour cookie_path et cookie_domain, cela amenait la SAPI à abandonner l'en-tête Set-Cookie ; pour cache_limiter, la valeur était silencieusement tronquée à l'octet NUL.

session_module_name() lance désormais une ValueError si name est une chaîne contenant des octets NUL.

session_encode() retourne désormais une chaîne vide au lieu de false pour les sessions vides. Elle ne retourne désormais false que lorsque les données de session n'ont pas pu être encodées. Cela se produit principalement avec le gestionnaire de sérialisation par défaut si une clé contient le caractère pipe (|).

Lorsque session.lazy_write est activé et qu'un gestionnaire de session implémente SessionUpdateTimestampHandlerInterface, les sessions qui ont été lues comme vides et restent vides au moment de l'écriture déclenchent désormais SessionUpdateTimestampHandlerInterface::updateTimestamp() au lieu de SessionHandlerInterface::write(). Auparavant, SessionHandlerInterface::write() était toujours appelée pour les sessions vides car session_encode() retournait false, contournant la comparaison de lazy_write. Les gestionnaires de session personnalisés qui s'appuient sur l'appel de SessionHandlerInterface::write() avec des données vides (par ex. pour détruire la session) devraient implémenter la même logique dans leur méthode SessionUpdateTimestampHandlerInterface::updateTimestamp().

Les valeurs par défaut de trois réglages INI de session ont changé afin de fournir un comportement sécurisé dès l'installation :

  • session.use_strict_mode vaut désormais 1 (auparavant 0). Le mode strict rejette les identifiants de session non initialisés, ce qui atténue la fixation de session. Les gestionnaires de session personnalisés qui s'appuyaient auparavant sur l'acceptation d'identifiants fournis de l'extérieur sans entrée de stockage correspondante doivent soit implémenter SessionUpdateTimestampHandlerInterface::validateId() et SessionIdInterface::create_sid(), soit définir explicitement ce réglage à 0.
  • session.cookie_httponly vaut désormais 1 (auparavant 0). Les cookies de session ne sont plus accessibles à JavaScript via document.cookie. Les applications qui lisent le cookie de session depuis JavaScript doivent définir explicitement ce réglage à 0.
  • session.cookie_samesite vaut désormais "Lax" (auparavant non défini). Les cookies de session ne sont plus envoyés lors des requêtes inter-sites autres que les navigations de premier niveau utilisant des méthodes HTTP sûres. Les applications qui dépendent de l'envoi des cookies de session lors de soumissions POST inter-sites doivent définir explicitement ce réglage à "None" (et définir également session.cookie_secure à 1).

SessionHandler::validateId() a été ajoutée et délègue au gestionnaire de sauvegarde configuré. Une sous-classe qui déclare SessionHandler::validateId() sans type de retour émet désormais un avertissement de dépréciation pour le type de retour bool provisoire. Une sous-classe qui surcharge SessionHandler::open() sans appeler parent::open() conserve son comportement précédent et émet un avertissement lorsqu'un identifiant est validé.

Shmop

shmop_open() lève désormais une ValueError lorsque l'argument key est en dehors de la plage key_t de la plateforme, au lieu de transmettre une clé tronquée au système d'exploitation.

SimpleXML

SimpleXMLElement::__construct() lève désormais une ValueError lorsque l'argument data contient des octets NUL, comme simplexml_load_file(). Avec dataIsURL défini, le chemin était auparavant tronqué au premier octet NUL. Sans lui, la chaîne était transmise à libxml, qui, avec les options par défaut, rejette un NUL sur les versions actuelles mais accepte le document tronqué sur les versions plus anciennes et avec LIBXML_RECOVER.

SOAP

L'option "classmap" de SoapClient et SoapServer rejette désormais les tableaux contenant des clés entières. Auparavant, les tableaux creux à clés entières et les tableaux à clés mixtes pouvaient être acceptés. SoapClient lance désormais une TypeError pour les options "classmap" qui ne sont pas des tableaux et une ValueError pour les tableaux contenant des clés entières, y compris lorsque l'option "exceptions" est désactivée.

L'analyse des WSDL/schémas XML rejette désormais les valeurs entières hors limites pour les contraintes d'occurrence et les facettes de restriction entières. Les valeurs négatives de minOccurs et maxOccurs sont également rejetées.

Les erreurs d'encodage SOAP rapportent désormais le type concerné ou l'opération défaillante dans le message d'erreur, au lieu du message générique Encoding: Violation of encoding rules. Le code qui compare le message exact peut nécessiter une mise à jour.

Sockets

socket_set_option() avec SO_ATTACH_REUSEPORT_CBPF nécessite désormais une value de type int et un level égal à SOL_SOCKET. Tout autre type de valeur lance une TypeError au lieu d'être converti, et tout autre niveau émet un avertissement et retourne false.

socket_set_option() avec SO_ATTACH_REUSEPORT_CBPF et une value égale à 0 détache désormais le filtre reuseport via SO_DETACH_REUSEPORT_BPF. Elle utilisait auparavant SO_DETACH_BPF, un alias de SO_DETACH_FILTER, qui laissait le programme reuseport attaché.

Sodium

Les fonctions de hachage de mots de passe sodium_crypto_pwhash(), sodium_crypto_pwhash_str(), sodium_crypto_pwhash_scryptsalsa208sha256() et sodium_crypto_pwhash_scryptsalsa208sha256_str() lancent désormais une ValueError au lieu d'une SodiumException lorsqu'un argument est hors limites, comme un opslimit ou un memlimit inférieur au minimum documenté. SodiumException est toujours lancée pour les échecs internes de libsodium.

SPL

Les implémentations de SplObjectStorage::getHash() ne peuvent plus modifier aucune instance de SplObjectStorage. Toute tentative en ce sens lance désormais une Error.

SplFileObject::next() fait désormais avancer le flux lorsqu'aucun appel précédent à SplFileObject::current() n'a mis une ligne en cache. Un appel ultérieur à SplFileObject::current() retourne la nouvelle ligne plutôt que la précédente.

SplFileObject::fgets() ne met plus en cache la ligne retournée pour les appels ultérieurs à SplFileObject::current(). SplFileObject::current() relit désormais depuis la position courante du flux au lieu de retourner la ligne que SplFileObject::fgets() vient de retourner.

SplFileObject::next() au-delà de la fin du fichier (EOF) n'incrémente plus SplFileObject::key() sans limite. SplFileObject::seek() au-delà de EOF produit désormais la même valeur de SplFileObject::key() que SplTempFileObject ; les deux retournaient auparavant des valeurs différentes.

DirectoryIterator::key() retourne désormais int|string, et DirectoryIterator::current() retourne string|SplFileInfo|static.

Sysvshm

shm_attach() lève désormais une ValueError lorsque l'argument key est en dehors de la plage key_t de la plateforme, au lieu de transmettre une clé tronquée au système d'exploitation.

URI

Uri\WhatWg\Url::__construct() définit désormais softErrors à un tableau vide lorsque le traitement de l'URL lance une exception, au lieu de conserver sa valeur. Les erreurs de validation de l'URL restent disponibles dans la propriété Uri\WhatWg\InvalidUrlException::$errors.

Uri\WhatWg\Url::__construct(), Uri\WhatWg\Url::parse(), les méthodes Uri\WhatWg\Url::with*() et Uri\WhatWg\UrlBuilder::build() rapportent désormais les erreurs de validation dans l'ordre où elles sont détectées. Cela inverse l'ordre de plusieurs erreurs par rapport à PHP 8.5.

Zip

ZipArchive::extractTo() lève désormais une TypeError pour l'argument files si une ou plusieurs des entrées ne sont pas des chaînes.

ZipArchive::addGlob() et ZipArchive::addPattern() lèvent désormais une TypeError lorsque l'option "remove_all_path" n'est pas de type bool, ou lorsque les options "comp_method", "comp_flags" ou "enc_method" ne sont pas de type int (les chaînes numériques sont converties), au lieu d'émettre un avertissement.

Sérialiser ou désérialiser une ZipArchive lance désormais une Exception. Une sous-classe peut surcharger __serialize() et __unserialize() pour effectuer un aller-retour via ZipArchive::closeString() et ZipArchive::openString().

Zlib

deflate_init() lève désormais une TypeError lorsque la valeur de l'option "level", "memory", "window" ou "strategy" n'est pas de type int.

inflate_init() lève désormais une TypeError lorsque la valeur de l'option "window" n'est pas de type int.

+add a note

User Contributed Notes

There are no user contributed notes for this page.