A great feature of PHP is the ability to throw and catch exceptions. This feature was introduced in PHP 5, and has been around for years in other languages like Python.
Exceptions make it easy to interrupt program flow in the event that something goes wrong. They allow you to customize how a program handles errors, and gracefully degrades an application. This week, we will discuss various exception handling techniques, and today we will discuss the basic dos and don’ts for exceptions.
First, what is an exception? An exception is an object that is “thrown” by your application. When an exception is thrown, it halts processing until the exception is either caught, or left unhandled. To throw an exception, you use the following syntax:
<?php
throw new Exception('my exception message');
There are a couple of things at work here: first, we are using the “new Exception” syntax to instantiate a new instance of the built-in Exception class. Second, we are using a special keyword in PHP called “throw” which allows for an exception to be placed onto the stack.
If left like this, the exception thrown above will bubble up and cause processing to halt at the point when the exception is raised. This is typical error behavior, but what makes exceptions special (and useful) is the ability to “catch” them.
<?php
try {
throw new Exception('my exception message');
}
catch (Exception $e)
{
// do some sort of error handling here
}
Catching exceptions allows us to try and recover from the error, or allow our application to degrade gracefully. In production, unhandled exceptions will cause the page to stop loading (or not load at all), but handled exceptions allow you the ability to redirect a user to an error page or do other error handling.
That is the basic syntax for using exceptions. But when should you use them and under what conditions? Here are some tips for making proper use of exceptions:
Exceptions are a part of object-oriented programming.
This may well be the most controversial point of this blog entry, but objects are really best used and should mostly be used with object-oriented programming. The exception itself is an object. PHP offers a number of error raising options that I recommend for use in procedural code, but exceptions should mostly be used with objects.
Extending exceptions is cool and encouraged.
As a developer you are allowed and encouraged to extend the base exception class on your own to create custom exceptions. These custom exceptions need not implement any custom methods; instead, you can use them to raise exceptions in different parts of your application. For example, you can raise a custom DatabaseException in the database class while raising a custom ActionException when actions are performed.
Exceptions can be extended like any other class:
class CustomException extends Exception {}
We can then throw CustomException. You can even further extend CustomException (for example if you want to implement certain custom methods and then have other exceptions use those methods). Note that in order to throw something it must extend the base Exception class; otherwise PHP will not allow it to be thrown.
Be sure that your exceptions honor layer abstraction.
One of the more complicated things about handling exceptions is that you want to honor layer abstraction when throwing and catching exceptions.
For example, let’s say that PDO raises an exception due to a unique key constraint in the database. Unhandled, it will bubble up to the top. If the PDO exception was caused by something in your Controller, allowing the PDO exception to bubble up would be a violation of layer abstraction.
A better choice would be to catch the PDO exception and wrap it in a Controller exception. For example:
<?php
try {
// some PDO action here
}
catch(PDOException $pdoE)
{
throw new ControllerException('There was an error: ' . $pdoE->getMessage() );
}
When the exception bubbles up, the PDO exception will have been handled, but the message will be included in a ControllerException. This is an acceptable way to handle exceptions that honors the principle of layer abstraction.
Truncated by Planet PHP, read more at the original (another 5386 bytes)