PHP 7.1: enhancements to errors handling

September 07, 2016php, php-7.1, english
 This has been written a few years ago and might not be up-to-date…

Cet article est aussi disponible en français.
This is the third post in a serie about PHP 7.1.

PHP 7.1 brings a couple of enhancements to errors and exceptions handling.

Catching Multiple Exception Types

First, we can now catch several distinct exception types with one single catch keyword: we only have to use a | between each exception type.

For example, if we have some exception types defined this way:

class Plop extends Exception {}
class Blah extends Exception {}
class Another extends Exception {}

We can throw an exception of any of these types, like below. The interesting part is the first catch block: it is going to handle Plop and Blah exceptions the same way:

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));

The principles of exceptions handling don’t change at all: this is only a small enhancement to the syntax. This will allow us to avoid copy-pasting the same handling block, when we need to use it for two distinct exception types.

‣ The RFC: Catching Multiple Exception Types

Throw Error in Extensions

PHP 7.0 introduced a major change in error handling: some of the fatal errors previously raised by the engine have been transformed to exceptions, instances of Error or one of its child classes.
PHP 7.1 generalizes this behavior to the majority of fatal errors that were previously raised by extensions bundled with PHP.

For example, unserializing an invalid string that should have represented a DateTime object no longer causes a Fatal Error with 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);

This portion of code, with an invalid $serialized string (I replaced a _ by a -), will now lead to this, with PHP 7.1:

Fatal error: Uncaught Error: Invalid serialization data for DateTime object in .../demo-01.php:5

Here, I got an Error, which I have no caught — and it leads to a Fatal Error.
I could have surrounded all this by a try/catch block, avoiding this fatal error and dealing with the case in a proper way.

‣ The RFC, listing all changed cases: Throw Error in Extensions