« How To Make Your Team’s Code Better | A better personal biography » |
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.
Brandon Savage is the author of Mastering Object Oriented PHP and Practical Design Patterns in PHP
Posted on 1/22/2013 at 6:00 am
b3ha (@_b3ha_) wrote at 1/22/2013 3:21 pm:
Hi,
Its a nice idea to use interfaces to grouping exceptions. With this concept, its easier to understand some parts of the code, so it might be increase the readability too.
Thanks for the post
Amy Stephen (@http://Twitter.com/AmyStephen) wrote at 1/24/2013 12:12 am:
Thanks very much, very useful, easy to understand and put into motion!
« How To Make Your Team’s Code Better | A better personal biography » |