PHP 8.6.0 RC3 a été tagué le 8 octobre 2026. Le calendrier prévoit la disponibilité générale le 19 novembre 2026, et RC4 ainsi que RC5 restent programmés. Des changements sont encore possibles avant la version finale. Cette analyse s’appuie sur les fichiers UPGRADING et NEWS du tag RC3 et sur les fonctionnalités effectivement intégrées. La recherche s’arrête au 11 octobre 2026.

L’ajout majeur est l’application partielle de fonctions. La proposition a été acceptée à l’unanimité et intégrée dans alpha3. Un appel utilisant ? pour un seul argument manquant ou ... pour zéro ou plusieurs arguments restants renvoie une Closure. La syntaxe strlen(...) repose sur le même concept sans argument déjà fixé. Cette fonctionnalité simplifie notamment les appels à array_map(). UPGRADING indique aussi que array_map() peut être compilé en boucle lorsqu’il reçoit une callable de première classe ou une application partielle.

L’opérateur pipe, arrivé avec PHP 8.5, exige une callable prenant un seul argument à droite de |>. L’application partielle évite l’emploi d’une fonction fléchée lorsqu’un appel pipé doit fixer plusieurs arguments. Avec un seul placeholder placé directement après |>, le compilateur peut produire un appel direct sans créer de Closure. Deux placeholders ou davantage entraînent toujours la création d’une Closure.

Les arguments liés sont évalués au moment où l’application partielle est créée. Une fonction fléchée réévalue son corps à chaque appel. La différence compte avec une expression variable telle que date('H:i:s'). Chaque ? crée un paramètre obligatoire, même si le paramètre d’origine possède une valeur par défaut. Les paramètres introduits par ... gardent leur caractère optionnel, et les paramètres optionnels non couverts utilisent toujours leur valeur par défaut. Certains exemples des anciens textes RFC ne décrivent donc plus le comportement de RC3.

Les propriétés readonly peuvent désormais déclarer une valeur par défaut, y compris dans les readonly classes. Cette valeur compte comme l’initialisation initiale, ce qui interdit une nouvelle affectation dans le constructeur. Pour une valeur configurable, un paramètre de constructeur promu avec une valeur par défaut convient mieux. __clone() et clone-with peuvent réinitialiser la propriété une fois. La fonction clamp(mixed $value, mixed $min, mixed $max): mixed applique les comparaisons PHP habituelles et accepte notamment les chaînes et les objets DateTimeInterface. Elle lève ValueError si la borne minimale dépasse la borne maximale ou si une borne vaut NAN.

Time\Duration est une classe finale readonly représentant des durées exactes à la nanoseconde. Des fabriques nommées permettent de créer des valeurs à partir de secondes, de minutes ou de chaînes de durée ISO 8601. Les comparaisons ainsi que add() et sub() sont disponibles. Les opérateurs + et - ne le sont pas. La classe ne s’intègre ni à DateTime ni à DateInterval, et des fonctions comme sleep() n’acceptent pas Duration. Son intérêt actuel concerne le typage des délais et l’API de polling.

Les valeurs par défaut des sessions représentent le principal risque immédiat. session.use_strict_mode passe de 0 à 1, session.cookie_httponly de 0 à 1 et session.cookie_samesite d’une valeur absente à Lax. PHP rejettera les identifiants de session qu’il n’a pas créés, JavaScript ne pourra plus lire le cookie via document.cookie et le cookie ne sera plus envoyé lors des requêtes POST intersites. Les gestionnaires de session personnalisés, les sessions partagées entre sous-domaines ou services, les bindings POST SAML et les callbacks de paiement doivent être testés. Les applications dépendant des anciennes valeurs doivent les définir explicitement.

La validation des arguments devient plus stricte dans le moteur. Les modes et flags invalides concernent notamment array_filter(), array_change_key_case(), pathinfo() et scandir(). Des nombres hors limites peuvent faire lever ValueError à number_format(), sleep() et usleep(). Les octets NUL dans getenv(), putenv(), parse_str(), setlocale() et dans des fonctions de fichiers comme file_exists(), is_file(), filesize() et stat() déclenchent désormais des exceptions. Ces valeurs pouvaient auparavant être tronquées ou rejetées silencieusement. trim(), ltrim() et rtrim() retirent aussi le caractère form feed par défaut. base_convert(), bindec(), hexdec() et octdec() émettent une notice après une conversion imprécise, et preg_grep() renvoie false en cas d’erreur d’exécution. GMP, Intl, GD, Sodium et d’autres extensions renforcent également leurs contrôles.

La nouvelle option INI error_include_args ajoute les arguments des fonctions aux messages d’erreur. Elle est désactivée par défaut. Les valeurs marquées avec #[\SensitiveParameter] sont masquées, mais les autres peuvent apparaître dans les journaux. Lors d’un manque de mémoire fatal, PHP appelle désormais abort(), avec un code de sortie 134 et la possibilité d’écrire un core dump. Les superviseurs et alertes fondés sur les codes de sortie doivent être vérifiés. Un foreach par référence peut revisiter des éléments après une compaction de tableau. ?? et empty() n’appellent plus __get() sur une propriété magique après qu’un appel à __isset() l’a écrite.

La plupart des dépréciations préparent PHP 9. Les alias scalaires is_integer(), is_long(), is_double() et doubleval() ont des équivalents canoniques. spl_object_hash() doit céder la place à spl_object_id(), qui renvoie un entier. Les données sérialisées et les clés de cache sont donc à contrôler. Le troisième argument de define(), spl_classes() et mysqli_get_charset() est déprécié. Les retours depuis finally, les valeurs renvoyées par __construct() ou __destruct(), les appels à is_a() ou is_subclass_of() avec une chaîne lorsque allow_string vaut false, ainsi que le passage d’objets à array_walk() ou http_build_query() demandent une vérification de l’intention.

Plusieurs méthodes de tri, de flags et de sérialisation d’ArrayIterator sont concernées, notamment asort(), ksort(), uasort(), setFlags() et serialize(). Les méthodes CSV de SplFileObject, comme fgetcsv(), fputcsv(), setCsvControl() et getCsvControl(), sont également dépréciées. Les gestionnaires de session personnalisés sans create_sid() et validateId() sont inclus. mbregex est le point à planifier rapidement, car la bibliothèque Oniguruma n’est plus maintenue. La famille mb_ereg(), mb_eregi(), mb_ereg_replace(), mb_split() et mb_regex_encoding() est dépréciée et doit disparaître en PHP 9.0. Une migration vers PCRE avec le modificateur u est souvent possible, mais les dialectes diffèrent et nécessitent des tests. Les dépréciations de list() et de l’alias gettext _() n’ont pas été adoptées.

Io\Poll apporte une primitive de boucle événementielle orientée objet. Elle comprend Context, une sélection automatique des backends epoll, kqueue, poll, event ports et WSAPoll, des watchers typés pour les handles de flux et wait() avec un délai Time\Duration. La page RFC affiche encore une ancienne signature de wait() fondée sur un entier. L’API vise les runtimes asynchrones, les serveurs de sockets et les gestionnaires de processus. Les contextes de flux peuvent convertir les erreurs en exceptions avec StreamErrorMode::Exception. Les clients HTTP, adaptateurs de stockage et tâches d’importation obtiennent ainsi une StreamException interceptable contenant les erreurs collectées. Le comportement par défaut reste celui des warnings.

L’extension URI reçoit les builders fluides Uri\Rfc3986\UriBuilder et Uri\WhatWg\UrlBuilder, l’inspection des types d’hôte et d’URI, ainsi qu’une fonction d’encodage en pourcentage WHATWG. Ces ajouts concernent les redirections, les URL signées et les contrôles SSRF. Les optimisations comprennent la mise en cache des closures sans état, la compilation d’appels printf() et array_map(), une VM TAILCALL plus rapide sous Windows avec Clang, un encodage JSON accéléré et des fonctions de tableaux et de chaînes plus rapides. Les gains attendus restent progressifs et dépendent de la charge.

True Async ne fait pas partie de la version, son RFC ayant été annulé. L’inférence automatique des closures statiques n’a pas été intégrée. Seule la mise en cache des closures sans état issue du RFC d’optimisation des closures a été retenue, et les closures explicitement déclarées static en tirent pleinement parti. SortDirection ajoute Ascending et Descending, mais les fonctions de tri existantes utilisent toujours SORT_ASC et SORT_DESC. Les constantes de scandir() restent inchangées. La nouvelle méthode de réflexion s’appelle ReflectionProperty::isWritable().

La migration devrait commencer par l’exécution complète de RC3 en CI, avec les messages E_DEPRECATED visibles, puis par la vérification de la compatibilité PHP 8.6 des dépendances. Il faut comparer la configuration effective des sessions et tester le login, le SSO et les callbacks de paiement de bout en bout. Les entrées utilisateur transmises aux fonctions de fichiers, d’environnement et de locale doivent couvrir leurs chemins d’erreur. mbregex, return dans finally et les méthodes SPL dépréciées doivent être recensés. Une préproduction soumise à un trafic proche de la production doit surveiller les journaux et les codes de sortie avant le déploiement. Les projets ayant plusieurs versions de retard ont besoin d’un plan de migration plus large.