Throwing Exceptions in PHP
Throwing a generic PHP exception is almost as simple as it sounds. All it takes is to instantiate an exception object—with the first parameter of the Exception constructor being the error message—and then, "throw" it.
throw new Exception('Exception message')
The most important thing to take note of is the message. Defined in the constructor, and accessed via the getMessage() method, the message is the human-readable error that can often be related to the end user.
The Exception class
To more effectively utilize exceptions within your application, it is important to understand how to create and throw your own PHP exception. But before we get into throwing custom PHP exceptions, let's first take a look at what an exception is under the hood, and how to define your own, starting with the global Exception class that all PHP exceptions stem from:
class Exception {
protected $message = 'Unknown exception'; // exception message
private $string; // __toString cache
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception
private $trace; // backtrace
private $previous; // previous exception if nested exception
public function __construct($message = null, $code = 0, Exception $previous = null);
final private function __clone(); // Inhibits cloning of exceptions.
final public function getMessage(); // message of exception
final public function getCode(); // code of exception
final public function getFile(); // source filename
final public function getLine(); // source line
final public function getTrace(); // an array of the backtrace()
final public function getPrevious(); // previous exception
final public function getTraceAsString(); // formatted string of trace
// Overrideable
public function __toString(); // formatted string for display
}
As we can see from the definition above, every built-in exception includes a few configurable properties: an exception message, an exception code, the source filename of the exception, and the line number of the exception in the source file. This information is what is used to create a human-readable—and diagnosable—exception object.
Throwing custom PHP exceptions
At their core, every exception is an extension of the global Exception class. What this means is that creating a custom exception, in its most basic form, requires only a class that extends the built-in Exception class.
namespace Custom;
class Exception extends Exception { }
With this custom exception created, we can then throw it as we would any other exception:
throw new CustomException('Exception message');
The advantage to inheriting from the built-in Exception class is that we can extend the core functionality of default exceptions. By overriding class properties like code, file, line, and message or the __toString()
method, we can coerce the exception data into a format we can work with.
namespace Custom;
class Exception extends Exception {
protected $details;
public function __construct($details) {
$this->details = $details;
parent::__construct();
}
public function __toString() {
return 'I am an exception. Here are the deets: ' . $this->details;
}
}
Writing to the error log
Outside of exception throwing, PHP also supports writing directly to the error log (more about that in Where are PHP Errors Logged?). The aptly named error_log function can be used to write raw messages to the error log without interrupting program execution. This is useful when you need to track debug data or keep track of caught and handled PHP exceptions.
bool error_log ( string $message [, int $message_type = 0 [, string $destination [, string $extra_headers ]]] )
Depending on the $message_type
, error_log
generally only requires one parameter: a message. While the other parameters can be used to direct where the error message should go, the most common use case is to use the default options to write directly to PHP's system logger.