Обработване на грешките в php

От доста време, не съм писал за нещо свързано php (тук някой трябва да възкликне – за всеобща радост) и днес реших да наваксам. Заиграх се малко, с грешки и начините по които да ги обработваме, по специално с set_exception_handler и register_shutdown_function функциите. Първата – set_exception_handler, се използва, за да регистрираме дефинирана от нас функция, която да се изпълни, ако възникне exception. Втората – register_shutdown_function, се използва, за да регистрираме дефинирана от нас функция, която да се изпълнява, когато приключи изпълнението на скрипта.
Общо взето идеята е, когато възникне някаква грешка, без значение дали е заради Exception или е php грешка, да можем да я запишем във файл или да я изпратим до себе си по email и да покажем някаква стандартна страница за грешка, на клиента който разглежда сайта. Ето и малко код:

[geshi lang=php]
define(‘DEBUG’, true);
set_exception_handler(array(‘myErrorHandler’, ‘onException’));
register_shutdown_function(array(‘myErrorHandler’, ‘onShutdown’));

class myErrorHandler {

public static function onException($exception) {
if (DEBUG) {
var_dump($exception);
} else {
self::logError($exception);
self::showErrorPage();
}
}

public static function onError($error) {
if (DEBUG) {
var_dump($error);
} else {
self::logError($error);
self::showErrorPage();
}
}

protected static function logError($error) {
// log the error here
}

protected static function showErrorPage() {
// display error page here
echo „We’re sorry, an error occurred while processing your request
„;
}

public static function onShutdown() {
$error = error_get_last();

if (!is_null($error) && $error['type'] == 1) { // TODO: use $error['type'] to filter the errors
self::onError($error);
}
}
}

class myClassA {

public function __construct() {
echo ‘in construct
‘;
}

public function run($a) {
if (!isset($a)) {
throw new InvalidArgumentException(__CLASS__ . ‘ ‘ . __METHOD__);
}
}

public function __destruct() {
echo ‘in deconstruct
‘;
}
}
[/geshi]

Дефинираме клас myErrorHandler със няколко статични метода: onException – Ще се изпълнява всеки път, когато възникне exception, а onError когато възникне php error. Предварително можем да укажем, за кои точно типове грешки да се извиква onError. Това става в onShutdown, използвайки $error['type']. Използваме logError и showErrorPage. за да запишем съответната грешка и да покажем страницата за грешка, когато възникне такава.
Веднъж след като приключим с писането на myErrorHandler използваме set_exception_handler и register_shutdown_function, за да регистрираме съответно onException и onShutdown методите. За да тестваме как работи всичко, създаваме и myClassA и отиваме към изпълнението на кода по-долу:

[geshi lang=php]
$a = new myClassA();
$a->run();
[/geshi]

Резултата е:

[geshi lang=php]
in construct

object(InvalidArgumentException)[2]
protected ‘message’ => string ‘myClassA myClassA::run’ (length=22)
private ‘string’ => string “ (length=0)
protected ‘code’ => int 0
protected ‘file’ => string ‘/media/sda2/home/saiman/www/debug/error.php’ (length=43)
protected ‘line’ => int 57
private ‘trace’ =>
array
0 =>
array
‘file’ => string ‘/media/sda2/home/saiman/www/debug/error.php’ (length=43)
‘line’ => int 67
‘function’ => string ‘run’ (length=3)
‘class’ => string ‘myClassA’ (length=8)
‘type’ => string ‘->’ (length=2)
‘args’ =>
array

in deconstruct
[/geshi]

При включен display_errors ще покаже и Warning, за това че сме пропуснали да подадем аргумент на run(). Прави впечатление, че след Exception-а се минава през __destruct на обекта. Същото нещо го има и при възникването на фатална грешка, което можем да тестваме с този код:

[geshi lang=php]
$a = new myClassA();
$a->function_not_exist();
[/geshi]

Ето го резултата:
[geshi lang=php]
in construct

array
‘type’ => int 1
‘message’ => string ‘Call to undefined method myClassA::function_not_exist()’ (length=55)
‘file’ => string ‘/media/sda2/home/saiman/www/debug/error.php’ (length=43)
‘line’ => int 67

in deconstruct
[/geshi]

А ето и какво се случва при define(‘DEBUG’, false):

in construct
We’re sorry, an error occurred while processing your request
in deconstruct

Сподели:
Edno23 Favit Svejo Twitter Facebook Google Buzz Delicious Google Bookmarks Digg
Публикувано в PHP. Постоянна връзка.

Вашият коментар

Вашият email адрес няма да бъде публикуван Задължителните полета са отбелязани с *

*

Можете да използвате тези HTML тагове и атрибути: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>