Où en est le support de PHP 5.6 et 8.4 ?
| Critère | PHP 5.6 | PHP 8.4 |
|---|---|---|
| Sortie | août 2014 | novembre 2024 |
| Fin des correctifs de bugs | janvier 2017 | décembre 2026 |
| Fin des correctifs de sécurité | décembre 2018 | décembre 2028 |
Statuts vérifiés le 08/11/2026 sur les pages officielles de version.
Les ruptures à traiter en premier
- Bloquant · 7.0Beaucoup d'erreurs fatales deviennent des exceptions Error ; un set_exception_handler() typé Exception provoque une erreur fatale si une Error est levée.source
- Bloquant · 7.0Retrait de toutes les fonctions ext/mysql (mysql_*) : il faut migrer vers mysqli ou PDO.source
- Bloquant · 7.1Appeler une fonction utilisateur avec trop peu d'arguments lève désormais ArgumentCountError (Error) au lieu d'un simple avertissement.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 7.0
- BloquantBeaucoup d'erreurs fatales deviennent des exceptions Error ; un set_exception_handler() typé Exception provoque une erreur fatale si une Error est levée.source
- BloquantRetrait de toutes les fonctions ext/mysql (mysql_*) : il faut migrer vers mysqli ou PDO.source
- BloquantRetrait des fonctions ereg* (remplacées par PCRE) et de preg_replace() avec le modificateur /e, à remplacer par preg_replace_callback().source
- À traiterLes erreurs de syntaxe lèvent ParseError : tout eval() doit gérer cette exception.source
- À traiterL'évaluation des variables indirectes passe en strict gauche-droite : $$foo['bar']['baz'] devient ($$foo)['bar']['baz'], à corriger avec des accolades.source
Extensions
- Extensions retirées : ereg, mssql, mysql et sybase_ct ; SAPI Apache 1 (apache, apache_hooks) et plusieurs SAPI obsolètes supprimés.source
- L'extension JSON est remplacée par JSOND : un nombre ne peut plus finir par un point (34.) et une chaîne vide n'est plus du JSON valide.source
Pièges rencontrés en migration
- foreach par valeur travaille sur une copie du tableau : les modifications faites pendant l'itération ne sont plus vues, ce qui change le comportement de boucles qui ajoutaient des éléments.source
- list() assigne désormais dans l'ordre de déclaration : list($a[], $a[], $a[]) inverse son résultat par rapport à PHP 5.source
Rector : LevelSetList::UP_TO_PHP_70
Passer à PHP 7.1
- BloquantAppeler une fonction utilisateur avec trop peu d'arguments lève désormais ArgumentCountError (Error) au lieu d'un simple avertissement.source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 7.0 → 7.1
Passer à PHP 7.2
- Bloquantcount() sur une valeur non dénombrable (null, scalaire, objet non Countable) émet un E_WARNING ; très fréquent dans le code hérité de PHP 5.source
- Bloquanteach() est dépréciée : à remplacer par foreach ou ArrayIterator.source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 7.1 → 7.2
Passer à PHP 7.3
- À traiterAvec le heredoc flexible, un marqueur de fin apparaissant dans le corps (même indenté) termine la chaîne et peut provoquer une erreur de syntaxe.source
- À traitercontinue ciblant un switch émet un avertissement : il se comporte comme break, alors que d'autres langages le traitent comme continue 2.source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 7.2 → 7.3
Passer à PHP 7.4
- À traiterAccéder à null, bool, int, float ou resource comme à un tableau ($null['key']) génère désormais une notice.source
- À traiterfn devient un mot réservé : il ne peut plus nommer une fonction ou une classe (reste possible pour une méthode ou une constante de classe).source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 7.3 → 7.4
Passer à PHP 8.0
- BloquantComparaison lâche nombre/chaîne non numérique : on compare désormais en chaîne, donc 0 == 'foo' vaut false. Fait sauter beaucoup de conditions legacy.source
- BloquantL'opérateur @ ne masque plus les erreurs fatales ; error_reporting par défaut passe à E_ALL et display_startup_errors est activé.source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 7.4 → 8.0
Passer à PHP 8.1
- BloquantPasser null à un paramètre non nullable d'une fonction interne est déprécié (strlen(null), trim(null)…) : source massive d'avertissements.source
- BloquantLes méthodes internes non finales exigent un type de retour compatible dans les classes filles ; sinon dépréciation, masquable par #[\ReturnTypeWillChange].source
Étape intermédiaire, détaillée sur sa propre page : migration PHP 8.0 → 8.1
À lire sur le blog : Migration PHP 8.1 vers 8.3 : les incompatibilités que personne ne mentionne
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
Étape intermédiaire, détaillée sur sa propre page : migration PHP 8.1 → 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 faire migrer votre application avec 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.
Sur une base aussi ancienne, l’audit d’abord : Bear Scan mesure tests, dépendances abandonnées et code mort avant de fixer le prix de la migration.
Questions fréquentes
À traiter en premier : Beaucoup d'erreurs fatales deviennent des exceptions Error ; un set_exception_handler() typé Exception provoque une erreur fatale si une Error est levée (PHP 7.0) ; Retrait de toutes les fonctions ext/mysql (mysql_*) : il faut migrer vers mysqli ou PDO (PHP 7.0) ; Appeler une fonction utilisateur avec trop peu d'arguments lève désormais ArgumentCountError (Error) au lieu d'un simple avertissement (PHP 7.1).
PHP 5.6 ne reçoit plus de correctifs de sécurité depuis décembre 2018.
En grande partie : le set LevelSetList::UP_TO_PHP_84 applique en une passe les transformations mécaniques jusqu’à PHP 8.4. Restent les changements de comportement (valeurs de retour, erreurs devenues fatales, extensions retirées), à couvrir par les tests et une relecture humaine.
Une migration Bear Upgrade démarre à 1 500 € HT. Pour une application Symfony, le calculateur pré-rempli avec PHP 5.6 → 8.4 donne l’estimation de votre projet ; le prix ferme est fixé au cadrage.
Pour aller plus loin
- PHP 8.6 arrive le 19 novembre, PHP 8.2 expire le 31 décembre
- Migration PHP 8.1 vers 8.3 : les incompatibilités que personne ne mentionne
- 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
- PHP 8.4 PDO subclasses : connexions Doctrine typées sans patch tiers
Sources
- www.php.net/manual/en/migration70.incompatible.php
- www.php.net/manual/en/migration70.changed-functions.php
- www.php.net/manual/en/migration71.incompatible.php
- www.php.net/manual/en/migration72.incompatible.php
- www.php.net/manual/en/migration72.deprecated.php
- www.php.net/manual/en/migration73.incompatible.php
- www.php.net/manual/en/migration74.incompatible.php
- www.php.net/manual/en/migration80.incompatible.php
- www.php.net/manual/en/migration81.deprecated.php
- www.php.net/manual/en/migration81.incompatible.php
- www.php.net/manual/en/migration82.deprecated.php
- www.php.net/manual/en/migration83.deprecated.php
- www.php.net/manual/en/migration83.incompatible.php
- www.php.net/manual/en/migration84.deprecated.php
- www.php.net/manual/en/migration84.incompatible.php