PHP 8.4.1 Released!

Modifications entrainant une incompatibilité ascendante

Modifications apportées à la gestion des erreurs et des exceptions

De nombreuses erreurs fatales et récupérables ont été converties en exceptions dans PHP 7. Ces exceptions d'erreur héritent de la classe Error, qui implémente elle-même l'interface Throwable (la nouvelle interface de base dont toutes les exceptions héritent).

Cela signifie que les gestionnaires d'erreurs personnalisés peuvent ne plus être déclenchés car des exceptions peuvent être levées à la place (provoquant de nouvelles erreurs irrécupérables pour les exceptions Error non interceptées).

Une description plus complète de la façon dont les erreurs fonctionnent en PHP 7 se trouve sur la page des erreurs PHP 7. Ce guide de migration énumérera simplement les modifications qui affectent la rétrocompatibilité.

set_exception_handler() n'est plus garanti de recevoir des objets Exception

Le code qui implémente un gestionnaire d'exceptions inscrit avec set_exception_handler() à l'aide d'une déclaration de type Exception provoquera une erreur fatale lorsqu'un objet Error est levé.

Si le gestionnaire doit fonctionner à la fois avec PHP 5 et 7, vous devriez supprimer la déclaration de type du gestionnaire, tandis que le code qui est migré pour travailler sur PHP 7 exclusivement peut simplement remplacer la déclaration de type Exception par Throwable.

<?php
// Code pour PHP 5 qui va se briser.
function handler(Exception $e) { ... }
set_exception_handler('handler');

// Compatible PHP 5 et 7.
function handler($e) { ... }

// PHP 7 seulement.
function handler(Throwable $e) { ... }
?>

Les constructeurs internes lèvent toujours des exceptions en cas d'échec

Auparavant, certaines classes internes retournaient null ou un objet inutilisable lorsque le constructeur échouait. Toutes les classes internes lèveront maintenant une Exception dans ce cas de la même manière que les classes d'utilisateurs.

Les erreurs d'analyse lèvent une ParseError

Les erreurs d'analyseur lèvent maintenant un objet ParseError. La gestion des erreurs pour eval() doit maintenant inclure un bloc catch qui peut gérer cette erreur.

Changements de gravité des avis E_STRICT

Tous les avis E_STRICT ont été reclassés à d'autres niveaux. La constante E_STRICT est conservée, donc les appels comme error_reporting(E_ALL|E_STRICT) ne provoqueront pas d'erreur.

Changements de gravité des avis E_STRICT
Situation Nouveau niveau/comportement
Indexation par une ressource E_NOTICE
Méthodes statiques abstraites Avis supprimé, ne déclenche aucune erreur
"Redéfinir" un constructeur Avis supprimé, ne déclenche aucune erreur
Incompatibilité de signature pendant l'héritage E_WARNING
Même propriété (compatible) dans deux traits utilisés Avis supprimé, ne déclenche aucune erreur
Accès à une propriété statique non statiquement E_NOTICE
Seules les variables doivent être attribuées par référence E_NOTICE
Seules les variables doivent être transmises par référence E_NOTICE
Appel de méthodes non statiques statiquement E_DEPRECATED

Modifications apportées à la gestion des variables

PHP 7 utilise maintenant une arborescence de syntaxe abstraite lors de l'analyse des fichiers sources. Cela a permis de nombreuses améliorations à la langue qui étaient auparavant impossibles en raison des limitations dans l'analyseur utilisé dans les versions antérieures de PHP, mais a abouti à la suppression de quelques cas spéciaux pour des raisons de cohérence, qui a abouti à casser la rétro-compatibilité. Ces cas sont détaillés dans cette section.

Modifications apportées à la gestion des variables, propriétés et méthodes indirectes

L'accès indirect aux variables, propriétés et méthodes sera maintenant évalué strictement dans l'ordre de gauche à droite, par opposition à la combinaison précédente de cas spéciaux. Le tableau ci-dessous montre comment l'ordre d'évaluation a changé.

Ancienne et nouvelle évaluation des expressions indirectes
Expression Interprétation PHP 5 Interprétation PHP 7
$$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz']
$foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz']
$foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']()
Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']()

Le code qui utilisait l'ancien ordre d'évaluation de droite à gauche doit être réécrit pour utiliser explicitement cet ordre d'évaluation avec des accolades (voir la colonne du milieu ci-dessus). Cela rendra le code compatible avec PHP 7.x et rétrocompatible avec PHP 5.x.

Cela affecte également le mot clé global. La syntaxe des accolades peut être utilisée pour émuler le comportement précédent si nécessaire :

<?php
function f() {
// Valide en PHP 5 uniquement.
global $$foo->bar;

// Valide en PHP 5 et 7.
global ${$foo->bar};
}
?>

Modifications apportées à la gestion des list()

la fonction list() n'assigne plus de variable dans l'ordre inverse

list() assignera désormais des valeurs aux variables dans l'ordre dans lequel elles sont définies, plutôt que dans l'ordre inverse. En général, cela affecte uniquement le cas où list() est utilisée en conjonction avec l'opérateur de tableau [], comme illustré ci-dessous :

<?php
list($a[], $a[], $a[]) = [1, 2, 3];
var_dump($a);
?>

Résultat de l'exemple ci-dessus en PHP 5 :

array(3) {
  [0]=>
  int(3)
  [1]=>
  int(2)
  [2]=>
  int(1)
}

Résultat de l'exemple ci-dessus en PHP 7 :

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

En général, il est recommandé de ne pas compter sur l'ordre dans lequel les affectations de la fonction list() se produisent, car il s'agit d'un détail d'implémentation qui peut changer à nouveau à l'avenir.

Les affectations de list() vides ont été supprimées

Les constructions de list() ne peuvent plus être vides. Les éléments suivants ne sont plus autorisés :

<?php
list() = $a;
list(,,) =
$a;
list(
$x, list(), $y) = $a;
?>
list() ne peut pas défaire chaîne de caractères

list() ne peut plus défaire les variables de chaîne de caractères. str_split() devrait être utilisé à la place.

L'ordre des éléments des tableaux a changé lorsque les éléments sont créés automatiquement pendant les affectations de référence

L'ordre des éléments dans un tableau a changé lorsque ces éléments ont été créés automatiquement en les référençant dans une assignation par référence. Par exemple :

<?php
$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Résultat de l'exemple ci-dessus en PHP 5 :

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Résultat de l'exemple ci-dessus en PHP 7 :

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Les parenthèses autour des arguments de fonction n'affectent plus le comportement

En PHP 5, l'utilisation de parenthèses redondantes autour d'un argument de fonction peut calmer les avertissements de normes strictes lorsque l'argument de fonction a été passé par référence. L'avertissement est maintenant toujours émis.

<?php
function getArray() {
return [
1, 2, 3];
}

function
squareArray(array &$a) {
foreach (
$a as &$v) {
$v **= 2;
}
}

// Generates a warning in PHP 7.
squareArray((getArray()));
?>

L'exemple ci-dessus va afficher :

Notice: Only variables should be passed by reference in /tmp/test.php on line 13

Changements concernant foreach

Des changements mineurs ont été faits sur le comportement de la structure de contrôle foreach, principalement sur la gestion du pointeur interne de tableau et la modification du tableau étant parcouru.

foreach ne modifie plus le pointeur interne de tableau

Antérieur à PHP 7, le pointeur interne de tableau était modifié pendant qu'un tableau était parcouru avec foreach. Cela n'est plus le cas, comme le montre l'exemple suivant :

<?php
$array
= [0, 1, 2];
foreach (
$array as &$val) {
var_dump(current($array));
}
?>

Résultat de l'exemple ci-dessus en PHP 5 :

int(1)
int(2)
bool(false)

Résultat de l'exemple ci-dessus en PHP 7 :

int(0)
int(0)
int(0)

foreach par valeur travaille sur une copie du tableau

Lors de l'utilisation du mode par défaut (par valeur), foreach travaille maintenant sur une copie du tableau en cours parcouru plutôt que sur le tableau lui-même. Cela signifie que les changements réalisés sur le tableau pendant son parcours n'affecteront pas les valeurs qui sont parcourues.

Le comportement du parcours de foreach par référence a été amélioré

Lors du parcours d'un tableau par référence, foreach identifie mieux les changements faits au tableau pendant son parcours. Par exemple, si des valeurs sont ajoutées à un tableau pendant son parcours, alors ces nouvelles valeurs seront également parcourues :

<?php
$array
= [0];
foreach (
$array as &$val) {
var_dump($val);
$array[1] = 1;
}
?>

Résultat de l'exemple ci-dessus en PHP 5 :

int(0)

Résultat de l'exemple ci-dessus en PHP 7 :

int(0)
int(1)

Parcours d'objets non-Traversable

Le parcours d'un objet non-Traversable est maintenant identique au parcours d'un tableau par référence. En conséquence l'amélioration du comportement lors de la modification d'un tableau pendant son parcours est également appliquée lorsque des propriétés sont ajoutées ou supprimées d'un objet.

Modifications apportées à la gestion d'entier

Littéraux octaux non valides

Auparavant, les littéraux octaux qui contenaient des nombres non valides étaient tronqués silencieusement (0128 a été pris comme 012). Désormais, un littéral octal non valide provoquera une erreur d'analyse.

Décalage de bits négatif

Les décalages de bits par nombres négatifs vont maintenant lancer une ArithmeticError:

<?php
var_dump
(1 >> -1);
?>

Résultat de l'exemple ci-dessus en PHP 5 :

int(0)

Résultat de l'exemple ci-dessus en PHP 7 :

Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2
Stack trace:
#0 {main}
  thrown in /tmp/test.php on line 2

Décalage de bits hors plage

Les décalages de bits (dans les deux sens) au-delà de la largeur de bit d'un entier retourneront toujours 0. Auparavant, le comportement de ces décalages était dépendant de l'architecture.

Changements apportés à la division par zéro

Auparavant, lorsque 0 a été utilisé comme diviseur pour les opérateurs de division (/) ou de modulo (%), un E_WARNING était émis et false était retourné. Désormais, l'opérateur de division retourne un float en tant que +INF,-INF ou NAN, comme spécifié par IEEE 754. Le E_WARNING de l'opérateur de modulo a été supprimé et lèvera une exception DivisionByZeroError.

<?php
var_dump
(3/0);
var_dump(0/0);
var_dump(0%0);
?>

Résultat de l'exemple ci-dessus en PHP 5 :

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Warning: Division by zero in %s on line %d
bool(false)

Résultat de l'exemple ci-dessus en PHP 7 :

Warning: Division by zero in %s on line %d
float(INF)

Warning: Division by zero in %s on line %d
float(NAN)

PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in %s line %d

Modifications apportées à la gestion des chaîne de caractères

Les chaînes hexadécimales ne sont plus considérées comme numériques

Les chaîne de caractères contenant des nombres hexadécimaux ne sont plus considérées comme numériques. Par exemple :

<?php
var_dump
("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));
?>

Résultat de l'exemple ci-dessus en PHP 5 :

bool(true)
bool(true)
int(15)
string(2) "oo"

Résultat de l'exemple ci-dessus en PHP 7 :

bool(false)
bool(false)
int(0)

Notice: A non well formed numeric value encountered in /tmp/test.php on line 5
string(3) "foo"

filter_var() peut être utilisé pour vérifier si une chaîne de caractères contient un nombre hexadécimal, et aussi pour convertir une chaîne de caractères de ce type en un entier :

<?php
$str
= "0xffff";
$int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX);
if (
false === $int) {
throw new
Exception("Invalid integer!");
}
var_dump($int); // int(65535)
?>

\u{ peut provoquer des erreurs

En raison de l'ajout de la nouvelle syntaxe d'échappement du point de code Unicode, les chaîne de caractères contenant un littéral \u{ suivi d'une séquence non valide provoquera une erreur fatale. Pour éviter cela, la barre oblique inverse principale doit être échappée.

Fonctions supprimées

call_user_method() et call_user_method_array()

Ces fonctions ont été dépréciées en PHP 4.1.0 en faveur de call_user_func() et call_user_func_array(). Vous pourriez également utiliser les fonctions variables et/ou l'opérateur ....

Toutes les fonctions ereg*

Toutes les fonctions ereg ont été supprimées. PCRE est une alternative recommandée.

Aliasmcrypt

La fonction obsolète mcrypt_generic_end() a été remplacée par mcrypt_generic_deinit().

De plus, les fonctions obsolètes mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() et mcrypt_ofb() ont été remplacées par l'utilisation de mcrypt_decrypt() avec la constante appropriée MCRYPT_MODE_*.

Toutes les fonctions ext/mysql

Toutes les fonctions ext/mysql ont été supprimées. Pour plus d'informations sur le choix d'une autre API MySQL, consultez choisir une API MySQL.

Toutes les fonctions ext/mssql

Toutes les fonctions ext/mssql ont été supprimées.

intl aliases

Les alias obsolètes datefmt_set_timezone_id() et IntlDateFormatter::setTimeZoneID() ont été supprimés et remplacés respectivement par datefmt_set_timezone() et IntlDateFormatter::setTimeZone().

set_magic_quotes_runtime()

set_magic_quotes_runtime(), ainsi que son alias magic_quotes_runtime(), ont été supprimées. Elles étaient obsolètes à partir PHP 5.3.0, et sans effet depuis la suppression des guillemets magiques en PHP 5.4.0.

set_socket_blocking()

L'alias obsolète set_socket_blocking() a été supprimé et remplacé par stream_set_blocking().

dl() avec PHP-FPM

dl() ne peut plus être utilisé avec PHP-FPM. Il continue à fonctionner dans les SAPIs CLI et Embed.

Fonctions GD Type1

Le support des polices PostScript Type1 a été supprimé de l'extension GD, entraînant la suppression des fonctions suivantes :

  • imagepsbbox()
  • imagepsencodefont()
  • imagepsextendfont()
  • imagepsfreefont()
  • imagepsloadfont()
  • imagepsslantfont()
  • imagepstext()

À la place, il est recommandé d'utiliser les polices TrueType et leurs fonctions associées.

Directives INI supprimées

Fonctionnalités supprimées

Les directives INI suivantes ont été supprimées car leurs fonctionnalités associées ont également été supprimées:

  • always_populate_raw_post_data
  • asp_tags

xsl.security_prefs

La directive xsl.security_prefs a été supprimée. Au lieu de cela, la méthode XsltProcessor::setSecurityPrefs() doit être appelée pour contrôler les préférences de sécurité sur une base du processeur.

Autres modifications rétro-incompatibles

Les nouveaux objets ne peuvent pas être attribués par référence

Le résultat de l'instruction new ne peut plus être assigné à une variable par référence :

<?php
class C {}
$c =& new C;
?>

Résultat de l'exemple ci-dessus en PHP 5 :

Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3

Résultat de l'exemple ci-dessus en PHP 7 :

Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3

Noms de classe, d'interface et de traits invalides

Les noms suivants ne peuvent pas être utilisés pour nommer des classes, des interfaces ou des traits :

En outre, les noms suivants ne doivent pas être utilisés. Bien qu'ils ne génèrent pas une erreur dans PHP 7.0, ils sont réservés pour une utilisation future et doivent être considérés comme obsolètes.

ASP et script PHP Tags supprimés

La prise en charge de l'utilisation des balises ASP et script pour délimiter le code PHP a été supprimée. Les balises affectées sont :

Suppression des balises ASP et script
Balise d'ouverture Balise de fermeture
<% %>
<%= %>
<script language="php"> </script>

Appels d'un contexte incompatible supprimés

Précédemment déconseillé dans PHP 5.6, les appels statiques effectués à une méthode non statique avec un contexte incompatible se traduiront désormais par la méthode appelée ayant une variable $this non définie et un avertissement d'obsolescence est émis.

<?php
class A {
public function
test() { var_dump($this); }
}

// Note: Does NOT extend A
class B {
public function
callNonStaticMethodOfA() { A::test(); }
}

(new
B)->callNonStaticMethodOfA();
?>

Résultat de l'exemple ci-dessus en PHP 5.6 :

Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8
object(B)#1 (0) {
}

Résultat de l'exemple ci-dessus en PHP 7 :

Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8

Notice: Undefined variable: this in /tmp/test.php on line 3
NULL

yield est maintenant un opérateur associatif à droite

La construction yield ne nécessite plus de parenthèses et a été remplacée par un opérateur associatif droit avec la priorité entre print et =>. Cela peut entraîner un changement de comportement :

<?php
echo yield -1;
// A été précédemment interprété comme
echo (yield) - 1;
// Et est maitenant interprété comme
echo yield (-1);

yield
$foo or die;
// A été précédemment interprété comme
yield ($foo or die);
// Et est maitenant interprété comme
(yield $foo) or die;
?>

Les parenthèses peuvent être utilisées pour lever l'ambiguïté sur ces cas.

Les fonctions ne peuvent pas avoir plusieurs paramètres avec le même nom

Il n'est plus possible de définir deux ou plusieurs paramètres de fonction avec le même nom. Par exemple, la fonction suivante déclenchera un E_COMPILE_ERROR:

<?php
function foo($a, $b, $unused, $unused) {
//
}
?>

Fonctions d'inspection des arguments signalent la valeur actuelle du paramètre

func_get_arg(), func_get_args(), debug_backtrace() et les traces d'exception ne signalent plus la valeur d'origine qui a été passée à un paramètre, mais fourniront plutôt la valeur actuelle (qui aurait pu être modifiée).

<?php
function foo($x) {
$x++;
var_dump(func_get_arg(0));
}
foo(1);?>

Résultat de l'exemple ci-dessus en PHP 5 :

1

Résultat de l'exemple ci-dessus en PHP 7 :

2

Les instructions Switch ne peuvent pas avoir plusieurs blocs par défaut

Il n'est plus possible de définir deux ou plusieurs blocs par défaut dans une instruction switch. Par exemple, l'instruction switch suivante déclenchera un E_COMPILE_ERROR :

<?php
switch (1) {
default:
break;
default:
break;
}
?>

$HTTP_RAW_POST_DATA a été supprimée

$HTTP_RAW_POST_DATA n'est plus disponible. Le flux php://input doit être utilisé à la place.

Les commentaires # dans le fichier INI ont été supprimés

La prise en charge des commentaires avec le préfix # dans les fichiers INI a été supprimée. ; (point-virgule) doit être utilisé à la place. Cette modification s'applique aux php.ini, ainsi qu'aux fichiers gérés par parse_ini_file() et parse_ini_string().

Extension JSON remplacée par JSOND

L'extension JSON a été remplacée par JSOND, provoquant trois incompatibilités BC mineures. Premièrement, un nombre ne doit pas se terminer par une virgule décimale (c.-à-d. 34. doit être modifié en 34.0 ou en 34). Deuxièmement, lors de l'utilisation de la notation scientifique, l'exposant e ne doit pas suivre immédiatement un point décimal (c.-à-d. 3.e3 doit être modifié soit en 3.0e3 ou en 3e3). Enfin, une chaîne vide n'est plus considérée comme du JSON valide.

Défaillance de la fonction interne sur le débordement

Auparavant, les fonctions internes devaient tronquer silencieusement les nombres produits à partir de contraintes de type float à entier lorsque le nombre était trop volumineux pour représenter un entier. Désormais, un E_WARNING sera émis et null sera renvoyé.

Correctifs aux valeurs de retour de gestionnaire de session personnalisé

Toutes les fonctions de prédicat implémentées par des gestionnaires de session personnalisés qui retournent false ou -1 seront des erreurs fatales. Si une valeur de ces fonctions autre qu'un booléen, -1 ou 0 est retournée, elle échouera et un E_WARNING sera émis.

Ordre de tri des éléments égaux

L'algorithme de tri interne a été amélioré, ce qui peut entraîner un ordre de tri différent des éléments, qui se comparent comme égaux auparavant.

Note:

Ne comptez pas sur l'ordre des éléments qui se comparent comme égaux; il pourrait changer à tout moment.

Instructions de coupure et de continuation mal placées

Les instructions break et continue en dehors d'une boucle ou d'une structure de contrôle switch sont maintenant détectées au moment de la compilation au lieu de l'exécution comme avant, et déclenchent un E_COMPILE_ERROR.

Constante interdite comme argument de break et continue

Les instructions break et continue ne permettent plus que leur argument soit une constante, et déclenchent une E_COMPILE_ERROR.

Mhash n'est plus une extension

L'extension mhash a été entièrement intégrée dans l'extension Hash. Par conséquent, il n'est plus possible de détecter le support mhash avec extension_loaded(); utiliser function_exists() à la place. En outre, mhash n'est plus rapporté par get_loaded_extensions() et les fonctionnalités connexes.

declare(ticks)

La directive declare(ticks) ne fuit plus dans des unités de compilation différentes.

add a note

User Contributed Notes

There are no user contributed notes for this page.
To Top