While most of the excitement surrounding the release of PHP 5 focused on its XML and object-oriented features, the Standard PHP Library (SPL) also saw some significant improvements that went mostly unnoticed. In the first of two articles covering the SPL, David Fells discusses the Exception class, which lets programs handle errors more gracefully and simplifies debugging.
Using our example code above, we can demonstrate a simple extension of the Exception class.
class DivisionByZeroException extends Exception{}
class WrongParameterTypeException extends Exception{}
class Math { function divide($divisor, $dividend = 1) { if (!is_numeric($divisor)) throw(new WrongParameterTypeException('Divisor is not a number')); if (!is_numeric($dividend)) throw(new WrongParameterTypeException('Dividend is not a number')); if ($dividend == 0) throw(new DivisionByZeroException('Division by zero'));
Using this approach, we are able to easily handle different errors in different ways, and this is where the real value of extending the Exception class comes in. We can chain an unlimited number of catch blocks together to capture the different types of exceptions that could have occurred. We could accomplish a similar feat using error codes (remember the second parameter to the Exception class constructor). To do this we would typically define class constants to identify the error type. We could ammend our code to look like this, for example.
Class Math { const DIVISION_BY_ZERO = 1; const WRONG_PARAMETER_TYPE = 2;
public static function divide($divisor, $dividend = 1) { if (!is_numeric($divisor)) throw(new Exception('Divisor is not a number', self::WRONG_PARAMETER_TYPE)); if (!is_numeric($dividend)) throw(new Exception('Dividend is not a number', self::WRONG_PARAMETER_TYPE)); if ($dividend == 0) throw(new Exception('Division by zero', self::DIVISION_BY_ZERO));
return ($divisor / $dividend); } }
try { print Math::divide(1, 0); } catch(Exception $e) { if ($e->getCode() == Math::WRONG_PARAMETER_TYPE)) die('You passed divide() a non-numeric value'); if ($e->getCode() == Math::DIVISION_BY_ZERO)) die('You tried to divide by zero'); print $e; }
The same end result is achieved with a different approach. Ultimately this is a matter of taste, but in my experience I have found it easier to keep up with exception classes. Regardless of your individual taste in approaches, this method of error handling is far more elegant and intuitive than anything available in PHP up until now, so take advantage of it.
Conclusion
Exceptions serve two main purposes: to simplify debugging and to allow for graceful error handling. They alllow a clean structure for identifying and creating errors at the script level, and allow simplified error recovery. The PHP 5 implementation of exceptions is, for all intents and purposes, identical to exception handling in Java, .NET and other languages capable of exception handling. Proper use of exceptions in PHP applications should help shed blobs of ugly legacy error handling and clean up code in general considerably. It allows the elimination of a lot of bulky error checks and the consolidation of error handling and recovery routines. Exceptions should be practiced religiously in PHP 5 applications.
Our next installment will discuss another important chunk of the SPL: Iterators. See you soon!