Переход к PHP5 - Система перехвата исключений

ОГЛАВЛЕНИЕ

Система перехвата исключений (exceptions)

Exceptions (исключения) - это неотъемлемая часть любого современного языка. Система перехвата исключений объединяет в себе оператор throw, стрктуру языка "try { .. } catch ()[ catch () ...]" и основной объект Exception. В отличии от Java exceptions, в PHP отсутствует завершающий блок finally.

Основное применение системы исключений состоит в использовании структуры try/catch для отделения основного кода программы и блоков обработки ошибок. Механизм exceptions позволяет также корректно обрабатывать исключения, возникшие не непосредственно в выполняемом коде, а в используемых функциях.

Следующий пример демонстрирует отделение кода от обработчиков нестандартных ситуаций:

/**
* Замечания:
* Конструктор DatabaseConnection может бросить DatabaseException
* Метод getUser() может бросить UserNotFoundException
* Метод sendMail() может бросить MailServiceException
*/
try {
$cn = new DatabaseConnection();
$admin = cn->getUser('Admin');
$admin->sendMail('Database check is complete');
} catch (
DatabaseException $e) {
print
"Невозможно создать соединение с базой данных. Причина: " . $e->getMessage();
} catch (
UserNotFoundException $e) {
print
"Пользователя не существует";
} catch (
MailServiceException $e) {
print
"Ошибка отправки письма: " . $e->getMessage();
} catch (
Exception $e) {
print
"Общая ошибка: " . $e->getMessage();
}

В общем случае, использование системы исключений можно заменить на использование структур if и goto или только if, но код программы в результате становиться значительно более громоздким.

Система исключений в PHP работает только с исключениями, "бросаемыми" оператором throw. Ошибки синтаксиса языка не обрабатываются блоками try/catch по очевидным причинам.

В PHP на данный момент определен только один класс исключений: Exception. Для более гибкой работы с системой сообщений можно добавлять свои классы исключений но наследовать их от базового класса Exception, что бы всегда можно было поймать исключение (catch exception).

Основными методами класса Exception являются: getMessage(), getCode(), getTrace(), getFile(), getTraceAsString(), _toString(). Все методы являются финальными, кроме конструктора и _toString(). Таким образом, дополнительная функциональность классов-потомков Exception (отправка почты с информацией о ошибке, запись в log) может быть реализована в конструкторе.

Класс Exception объявляется непосредственно в PHP Engine, но его примерная модель может быть представленна таким образом (по материалам www.zend.com):

class Exception {
function
__construct(string $message=NULL, int $code=0) {
if (
func_num_args()) {
$this->message = $message;
}
$this->code = $code;
$this->file = __FILE__; // of throw clause
$this->line = __LINE__; // of throw clause
$this->trace = debug_backtrace();
$this->string = StringFormat($this);
}

protected
$message = 'Unknown exception'; // exception message
protected $code = 0; // user defined exception code
protected $file; // source filename of exception
protected $line; // source line of exception

private $trace; // backtrace of exception
private $string; // internal only!!

final function getMessage() {
return
$this->message;
}
final function
getCode() {
return
$this->code;
}
final function
getFile() {
return
$this->file;
}
final function
getTrace() {
return
$this->trace;
}
final function
getTraceAsString() {
return
self::TraceFormat($this);
}
function
_toString() {
return
$this->string;
}
static private function
StringFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns all relevant information as a string
}
static private function
TraceFormat(Exception $exception) {
// ... a function not available in PHP scripts
// that returns the backtrace as a string
}
}