PHP 7.1 : la gestion d'erreurs et ses améliorations
7 septembre 2016 —This post is also available in English.
Ceci est le troisième article d’une série à propos de PHP 7.1.
PHP 7.1 apporte plusieurs améliorations au niveau de la gestion des erreurs ou des exceptions.
Catching Multiple Exception Types
Tout d’abord, nous pouvons désormais attraper plusieurs types d’exceptions différents avec le mot-clé catch
: il suffit de séparer les types d’exceptions par un |
.
Par exemple, si nous avons plusieurs types d’exceptions définis de la manière suivante :
class Plop extends Exception {}
class Blah extends Exception {}
class Another extends Exception {}
Nous pouvons lever une exception d’un type ou d’un autre, comme ci-dessous. La partie intéressante est le premier bloc catch
, qui va gérer de la même manière les exceptions de types Plop
et Blah
:
try {
switch (mt_rand(0, 2)) {
case 0: throw new Plop();
case 1: throw new Blah();
case 2: throw new Another();
}
}
catch (Plop | Blah $e) {
printf("1er catch : %s\n", get_class($e));
}
catch (Another $e) {
printf("2nd catch : %s\n", get_class($e));
}
Le principe de la gestion d’exceptions ne change nullement : il s’agit ici uniquement d’un enrichissement de la syntaxe. Nous évitons ainsi le copier-coller deux fois du même bloc de gestion, lorsqu’il doit être utilisé pour deux types d’exceptions différents.
‣ La RFC : Catching Multiple Exception Types
Throw Error in Extensions
PHP 7.0 a introduit un changement important au niveau de la gestion d’erreurs : une partie des erreurs fatales levées par le moteur ont été converties en exceptions, de type Error
ou d’une classe en héritant.
PHP 7.1 étend ce comportement à la majorité des erreurs fatales qui étaient auparavant levées par des extensions fournies avec PHP.
Par exemple, dé-sérializer une chaine invalide qui aurait dû correspondre à un objet DateTime
ne lève plus une Fatal Error
avec PHP 7.1 :
// 'timezone-type' au lieu de 'timezone_type'
$serialized = 'O:8:"DateTime":3:{s:4:"date";s:26:"2016-08-14 12:31:50.000000";s:13:"timezone-type";i:3;s:8:"timezone";s:3:"UTC";}';
$dt = unserialize($serialized);
var_dump($dt);
Cette portion de code, avec une chaine $serialized
incorrecte (j’ai remplacé un _
par un -
), mènera en PHP 7.1 à ceci :
Fatal error: Uncaught Error: Invalid serialization data for DateTime object in .../demo-01.php:5
J’ai ici pris une Error
, que je n’ai pas attrapée et qui a donc mené à une Fatal Error.
J’aurais pu entourer tout ceci d’un bloc try
/catch
et éviter cette erreur fatale et gérer convenablement le cas.
‣ La RFC, qui liste l’ensemble des cas adaptés : Throw Error in Extensions