A Crash Course of Changes to Exception Handling in PHP 7

Exception handling saves your code in the most unusual circumstances. PHP 7 has introduced two new classes that assist a developer in handling errors with ease, and that’s what we’ll look at in this post. Before the introduction of these classes in PHP 7, exception error classes were written to handle the different types of errors.

Throwable Class

Throwable is the interface from which Exception and Error classes branch out. This particular class helps you catch any throwable errors, irrespective of whether they are an exception or an error. For example:

Error Class

The Error class in PHP 7 is a new type of class that handles the different errors – they are either fatal errors or type errors, and this class is only for internal PHP errors. Error is divided into four subclasses:

A thing to keep in mind before upgrading to PHP 7 is that if you have defined a custom Error class, you have to make sure you changed the name before upgrading. If you don’t, you will get a fatal error.

Let’s discuss the above four classes one by one.

ArithmeticError

This error shows up when performing mathematical operations. For example, when you are using intdiv():

If you use the same method as above and change the % to /, you will get a warning instead and the result can be any one of these: +INF, -INF, or NAN. If you want this to result in an exception, better use an error handler that transforms the warning into a thrown exception.

However, you will have the DivisionByZeroError exception if you execute the following code:

TypeError

This error is mostly used with the Scalar Type declarations in PHP 7. The error will be shown when you have created a function or variable of a specific data type and you are trying to save a value of a different data type. For example:

If you run the above code, a TypeError will be thrown and you will get must be of the type integer, string was given error. If you run the above code without declare(strict_types=1); you won’t get any problems and the result will be 7, unless you change the number to a non-numerical string.

ParseError

This error is thrown when using eval() to insert a new line of code or using an external PHP file which contains a syntax error. Before ParseError, when you had a syntax error in your external PHP file or in eval(), your code was broken and a fatal error was shown. For example, let’s assume we have a PHP file with the following code:

When this code is executed, syntax error, unexpected end of file is shown instead of a fatal error. Before this class was introduced, it was almost impossible to handle syntax and fatal errors with ease.

AssertionError

Before the introduction of the AssertionError class, we had to create our own functions to handle assertion exceptions when binding a custom function using assert_options(). This error will only be shown when an assertion made via assert() fails. To work with it, you first need to configure the assert directives in PHP.ini:

Assert.exception: By default its value is 0 and it only generates a warning for the object rather than showing an error. However, when the value is changed to 1, then it will throw an exception or an Assertion Error which can be caught.

Zend.assertions: By default, it’s value is -1 which is for production mode, i.e., the assertion code will not be generated. When it is set to 1 it will be in development mode in which assertion code will be generated and executed. When it is set to 0, assertion code will be generated but won’t be executed during runtime.

When the above code is executed, you will get only a warning: "assert(): Two is less than one failed" and your exception will not be caught because assert.exception is 0. In order to make AssertionError catch the assert exception, we need to change assert.exception to 1. So when you run the following code:

Instead of the warning, you will see that an error is caught and only an error message will be shown, i.e. “Two is less than one.”

Since the introduction of the new classes, many of the fatal and recoverable fatal errors have been inherited from the Error class. It is not guaranteed that your custom handler, which you have set by using set_exception_handler(), will catch those errors. So, if you want to throw some custom exceptions in your code, you don’t have to reset your custom handler as it can now catch the errors by just using Throwable.

Summary

If you are using a PHP version older than 7, you should keep these things in mind before transitioning. To be safe, you can also look at the php 7 upgrade guide.

Have the new error and extension classes caused you any grief? Do you like or dislike their introduction in PHP 7? What do you hope to see changed about them, if anything?