Exceptions are especially useful when used in conjunction with code in a try/catch block. Using this construct, however, can be awkward in some situations, making code virtually unreadable. Another consideration is that many classes end up throwing exceptions that you have not anticipated. In such cases, it would be highly desirable to have some sort of fallback exception handler.
Application\Error\Handler:namespace Application\Error;
class Handler
{
// code goes here
}set_exception_handler() to assign the exceptionHandler() method (in this class) as the fallback handler:protected $logFile;
public function __construct(
$logFileDir = NULL, $logFile = NULL)
{
$logFile = $logFile ?? date('Ymd') . '.log';
$logFileDir = $logFileDir ?? __DIR__;
$this->logFile = $logFileDir . '/' . $logFile;
$this->logFile = str_replace('//', '/', $this->logFile);
set_exception_handler([$this,'exceptionHandler']);
}exceptionHandler() method, which takes an Exception object as an argument. We record the date and time, the class name of the exception, and its message in the log file:public function exceptionHandler($ex)
{
$message = sprintf('%19s : %20s : %s' . PHP_EOL,
date('Y-m-d H:i:s'), get_class($ex), $ex->getMessage());
file_put_contents($this->logFile, $message, FILE_APPEND);
}try/catch block in our code, this will override our universal exception handler. If, on the other hand, we do not use try/catch and an exception is thrown, the universal exception handler will come into play.First, place the code shown in the preceding recipe into a Handler.php file in the Application\Error folder. Next, define a test class that will throw an exception. For the purposes of illustration, create an Application\Error\ThrowsException class that will throw an exception. As an example, set up a PDO instance with the error mode set to PDO::ERRMODE_EXCEPTION. You then craft an SQL statement that is guaranteed to fail:
namespace Application\Error;
use PDO;
class ThrowsException
{
protected $result;
public function __construct(array $config)
{
$dsn = $config['driver'] . ':';
unset($config['driver']);
foreach ($config as $key => $value) {
$dsn .= $key . '=' . $value . ';';
}
$pdo = new PDO(
$dsn,
$config['user'],
$config['password'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->query('This Is Not SQL');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$this->result[] = $row;
}
}
}Next, define a calling program called chap_13_exception_handler.php that sets up autoloading, uses the appropriate classes:
<?php
define('DB_CONFIG_FILE', __DIR__ . '/../config/db.config.php');
$config = include DB_CONFIG_FILE;
require __DIR__ . '/../Application/Autoload/Loader.php';
Application\Autoload\Loader::init(__DIR__ . '/..');
use Application\Error\ { Handler, ThrowsException };At this point, if you create a ThrowsException instance without implementing the universal handler, a Fatal Error is generated as an exception has been thrown but not caught:
$throws1 = new ThrowsException($config);

If, on the other hand, you use a try/catch block, the exception will be caught and your application is allowed to continue, if it is stable enough:
try {
$throws1 = new ThrowsException($config);
} catch (Exception $e) {
echo 'Exception Caught: ' . get_class($e) . ':' . $e->getMessage() . PHP_EOL;
}
echo 'Application Continues ...' . PHP_EOL;You will observe the following output:

To demonstrate use of the exception handler, define a Handler instance, passing a parameter that represents the directory to contain log files, before the try/catch block. After try/catch, outside the block, create another instance of ThrowsException. When you run this sample program, you will notice that the first exception is caught inside the try/catch block, and the second exception is caught by the handler. You will also note that after the handler, the application ends:
$handler = new Handler(__DIR__ . '/logs');
try {
$throws1 = new ThrowsException($config);
} catch (Exception $e) {
echo 'Exception Caught: ' . get_class($e) . ':'
. $e->getMessage() . PHP_EOL;
}
$throws1 = new ThrowsException($config);
echo 'Application Continues ...' . PHP_EOL;Here is the output from the completed example program, along with the contents of the log file:

set_exception_handler() function. Have a look, especially, at the comment (posted 7 years ago, but still pertinent) by Anonymous that clarifies how this function works: http://php.net/manual/en/function.set-exception-handler.php.