Aller au contenu principal

Migration PHP · 8.1 → 8.2 → 8.3 → 8.4

Migrer de PHP 8.1 à PHP 8.4

PHP 8.1 ne reçoit plus de correctifs de sécurité depuis décembre 2025 ; PHP 8.4 reste couvert par les correctifs de sécurité jusqu’en décembre 2028. La montée traverse 3 versions (8.2, 8.3 et 8.4), chacune avec ses incompatibilités documentées dans le manuel PHP. 2 ruptures à fort impact sur le parcours. Première rupture à traiter : la création de propriétés dynamiques est dépréciée, sauf avec #[\AllowDynamicProperties] ; stdClass reste autorisée. Impact fort sur les entités et DTO hérités.

Où en est le support de PHP 8.1 et 8.4 ?

Support de PHP 8.1 et 8.4
CritèrePHP 8.1PHP 8.4
Sortienovembre 2021novembre 2024
Fin des correctifs de bugsnovembre 2023décembre 2026
Fin des correctifs de sécuritédécembre 2025décembre 2028

Statuts vérifiés le 08/11/2026 sur les pages officielles de version.

Les ruptures à traiter en premier

  1. Bloquant · 8.2La création de propriétés dynamiques est dépréciée, sauf avec #[\AllowDynamicProperties] ; stdClass reste autorisée. Impact fort sur les entités et DTO hérités.source
  2. À traiter · 8.2L'interpolation "${var}" et "${expr}" est dépréciée : utiliser "$var" ou "{$var}".source
  3. Bloquant · 8.4Paramètre implicitement nullable (Type $p = null) déprécié : écrire ?Type ou Type|null. Touche massivement le code hérité et les dépendances.source

Le chemin de migration, étape par étape

Chaque version mineure de PHP a son guide de migration officiel ; on les applique dans l’ordre, avec la CI au vert entre deux étapes. Avant de lancer le chantier, mesurer la dette avec un Bear Scan chiffre la dette qui ralentira chaque étape.

Passer à PHP 8.2

  • BloquantLa création de propriétés dynamiques est dépréciée, sauf avec #[\AllowDynamicProperties] ; stdClass reste autorisée. Impact fort sur les entités et DTO hérités.source
  • À traiterL'interpolation "${var}" et "${expr}" est dépréciée : utiliser "$var" ou "{$var}".source
  • À traiterCallables relatifs ("self::method", ["parent", "method"]) dépréciés quand $callable() ne les accepte pas.source
  • À traiterutf8_encode() et utf8_decode() sont dépréciées ; les encodages mbstring HTML-ENTITIES, Base64, QPrint et Uuencode aussi.source
  • Mineurglob() renvoie un tableau vide, et non false, si open_basedir restreint tous les chemins ; FilesystemIterator::SKIP_DOTS n'est plus forcé.source

Extensions

  • Nouvelle extension Random ; ODBC, PDO_ODBC, OCI8, cURL et OpenSSL reçoivent des ajustements.source
  • Les méthodes DateTime::createFromImmutable() et DateTimeImmutable::createFromMutable() ont un type de retour tentatif static.source

Pièges rencontrés en migration

  • Les dépréciations de propriétés dynamiques apparaissent à l'exécution, pas à la compilation : couvrir les chemins rares (cron, hydratation, tests) avant la mise en production.source
  • Plusieurs bibliothèques anciennes encodent en UTF-8 via utf8_encode() : un grep dans vendor/ évite des centaines de dépréciations.source

Rector : LevelSetList::UP_TO_PHP_82

Guide officiel de migration vers PHP 8.2

À lire sur le blog : PHP 8.6 arrive le 19 novembre, PHP 8.2 expire le 31 décembre

Passer à PHP 8.3

  • À traiterIncrémenter ou décrémenter des chaînes vides ou non numériques est déprécié ; utiliser str_increment(). L'incrément de chaînes non numériques est soft-déprécié.source
  • À traiterrange() durci : TypeError pour objets, tableaux et ressources, ValueError pour un pas à 0 ou négatif sur une plage croissante, avertissement pour une chaîne vide.source

Étape intermédiaire, détaillée sur sa propre page : migration PHP 8.2 → 8.3

À lire sur le blog : Migration PHP 8.1 vers 8.3 : les incompatibilités que personne ne mentionne · Docker multi-stage builds : image PHP 8.3 de 800 Mo à 80 Mo

Passer à PHP 8.4

  • BloquantParamètre implicitement nullable (Type $p = null) déprécié : écrire ?Type ou Type|null. Touche massivement le code hérité et les dépendances.source
  • À traiterexit() et die() se comportent comme des fonctions : soumis à strict_types et lèvent TypeError pour un type invalide.source
  • À traiterLe niveau E_STRICT est supprimé et sa constante déclarée dépréciée ; trigger_error() avec E_USER_ERROR est déprécié.source
  • À traiterModification indirecte de propriétés readonly dans __clone() interdite ; la récursion pendant une comparaison lève une Error.source
  • Mineurround() lève ValueError pour un mode invalide, str_getcsv() exige des séparateurs d'un octet, et nommer une classe _ est déprécié.source

Extensions

  • Migration ressource vers objet pour DBA, ODBC et SOAP.source
  • opcache.interned_strings_buffer : maximum relevé à 32767 sur 64 bits (4095 avant) ; nouveaux avertissements ou exceptions dans curl, gd, intl, mbstring, session, xml.source

Pièges rencontrés en migration

  • Les dépréciations de types implicitement nullables viennent surtout des dépendances : mettre à jour les paquets de vendor/ (composer outdated) avant de basculer la production.source
  • Une API qui passait n'importe quel type à exit() (ex. un tableau ou un objet) échoue désormais en TypeError dans les scripts et commandes console.source

Rector : LevelSetList::UP_TO_PHP_84

Guide officiel de migration vers PHP 8.4

À lire sur le blog : Doctrine ORM 3.4.0 : Lazy Objects natifs PHP 8.4 en production · Docker PHP 8.4 production : multi-stage, non-root et scan Trivy en CI

Ce que PHP 8.4 vous apporte

  • 8.4 : Property hooks : logique get/set attachée aux propriétés, avec propriétés virtuelles sans valeur de support.source
  • 8.4 : Visibilité asymétrique des propriétés : la visibilité en écriture se règle séparément de la lecture.source
  • 8.4 : Objets lazy dont l'initialisation est différée jusqu'au premier accès, utile aux frameworks et à l'injection de dépendances.source
  • 8.4 : Attribut #[\Deprecated] pour marquer fonctions, méthodes et constantes de classe (erreur E_USER_DEPRECATED).source
  • 8.4 : Chaînage direct d'une expression new sans parenthèses : new Foo()->bar().source

Combien coûte cette migration ?

À partir de 1 500 € HT

Pour la migration accompagnée Bear Upgrade, Rector tourne d’abord en dry-run sur les transformations mécaniques, Claude Code traite les cas que Rector ne couvre pas, puis un développeur senior relit chaque Merge Request. Votre équipe veut reprendre la main ensuite ? Pensez à apprendre à piloter Claude Code sur votre code. Exemple concret : la migration Symfony d’un e-commerce bordelais, et après la migration, la maintenance des versions garde le socle à jour.

Questions fréquentes

Pour aller plus loin

Sources

Votre migration PHP 8.1 → 8.4, livrée en Merge Requests

CI au vert garantie 7 jours après le merge. Un appel de cadrage suffit pour fixer le périmètre, le prix et le délai.