In PHP (as well as many other object oriented languages), exceptions are simply objects, which can be extended and reused. PHP makes them special in the sense that only exceptions that inherit from the base class Exception are throwable by the interpreter (you cannot throw any generic object you create).

Most developers are therefore aware of the ability to extend exceptions, thus giving them unique, typehintable values that can be identified, caught and handled.

<?php class MyException extends Exception {} try { // some code here throw new MyException('exception message'); } catch (MyException $e) { // handle exception here } ?>

Using interfaces for exceptions

PHP has a number of drawbacks in terms of extending the base exception class, namely that you cannot extend multiple classes at the same time. For example, you cannot extend both Exception and MyException in a class; this is not possible. PHP seeks to address some of these problems with the introduction of traits, but traits are not typehintable.

However, interfaces provide us an opportunity to create exceptions that share multiple different groups of problems. For example:

<?php interface NotCountableException {} interface NotIterableException {} class NotUsableException extends Exception implements NotCountableException, NotIterableException {} try { // If it's not countable we raise the not usable exception throw new NotUsableException('not countable'); } catch (NotCountableException $e) { // we can handle the exception } ?>

This is also useful in library code, when you want to have a base exception type that applies to all exceptions for a particular library. By implementing the exception interface, you can typehint on that interface no matter the inheritance chain for the actual exception.

The benefit of interfaces over inheritance

It might seem unusual to use an interface for exceptions; after all, exceptions are raised for specific kinds of errors. But exception classes are meant to be specific (e.g. class RecordNotFoundInDatabase), while interfaces provide flexibility to identify generic exception types (interface DatabaseError). By being able to group the exception types by interface, without having a long inheritance chain, it allows for the inclusion of multiple types when necessary, and greater flexibility in code. Since you cannot remove a particular parent class from the inheritance chain (but you can remove an interface from your own implementation should you so desire), this increases flexibility.

This is also useful in code that is meant to be reused like library code. The base exception in Ralph Schindler’s article is one example; another example is providing different interface types for developers to implement in their own exceptions when extending or implementing the library. By providing base exception interfaces as well as collection interfaces, you increase the re-usability of your code.

For an in-depth analysis of exception handling in object oriented PHP, as well as other great object oriented PHP topics, check out Mastering Object Oriented PHP.

Frustrated with your company’s development practices? You don't have to be! No matter what the issues are, they can be fixed. You can begin to shed light on these issues with my handy checklist. Plus, I'll help you with strategies to approach the issues at the organization level and "punch above your weight."

Great! We'll be updating you soon on best practices for your team!

Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP