Частый посетитель
Покинул форум
Сообщений всего: 979
Дата рег-ции: Окт. 2011
Откуда: Россия г. Нижний Новгород
Помог: 25 раз(а)
[+]
|
Итак, я хочу сразу сказать, что эта "статья" навеяна мне некоторыми статьями с хабра :
http://habrahabr[dot]ru/blogs/php/134557/ - Битовые операции
http://ru[dot]wikipedia[dot]org/wiki/%D0[dot][dot][dot]1%86%D0%B8%D0%B8 - Немного теории лично от Вики
http://www.php.net/manual/ru/lan...tors.bitwise.php - А так-же офф мануалы.
Я сразу скажу, что материал ориентирован на людей которые прекрасно понимают, что такое ООП и с чем его едят.
Поехали :
1) Пишем класс по отлову ошибок, не пойманных исключений. Код почему-то у меня получился достаточно "тяжелый" хотя и его очень мало, но Adobe DreamWeaver CS 5.5 местами помечает строки красным - хотя всё работает. Думаю у кого NetBeans 7.1 или аналогичные редакторы проблем не будет, а если будут не стоит на них существенно зацикливаться, нам всё выдадут наши новые ошибки.
Спойлер (Отобразить)PHP:
скопировать код в буфер обмена
final class Errors { // - Я почему-то решил, что не стоит создавать экземпляр этого класса, поэтому используются статически методы, а конструкторы защищены. protected function __clone() {} protected function __wakeup() {} protected function __construct() {} // В этих массивах мы будем хранить наши ошибки которые "выскакивают" и исключения в процессе работы скрипта. Но выводить мы их будем - или не будем в самом конце, зачем они нам нужны по середине работы?? static public $Errors = array(), // - В этом массиве мы храним побитовые маски ошибок которые могут выскачить в процессе работы, все кроме индекса 0, это я добавил сам, т.к исключения по сути не нуждаются в номере ошибки. static protected $ErrorCodes = array( 0 => 'Uncaught exception', 1 => 'ERROR', 2 => 'WARNING', 4 => 'PARSE', 8 => 'NOTICE', 16 => 'CORE ERROR', 32 => 'CORE WARNING', 64 => 'COMPILE ERROR', 128 => 'COMPILE WARNING', 256 => 'USER ERROR', 512 => 'USER WARNING', 1024 => 'USER NOTICE', 2048 => 'STRICT', 4096 => 'RECOVERABLE ERROR', 8192 => 'DEPRECATED', 16384 => 'USER DEPRECATED', 32767 => 'ALL', ); // Метод инициализации класса. static public function Init($callback=NULL){ // Сразу запрещаем вывод ошибок. Если на хостинге запрещено пользоваться ini_set попробуйте функция error_reporting(0); они абсолютно одинаковы. // Игнорируем остановку соединения с клиентом, тоесть если он нажмет в браузере кнопку "Стоп", скрипт должен продолжить работу в фоновом режиме. // Т.е методы статические, создаем переменную и помещаем в неё массив ошибок и их битовых масок, для чего они нужны я расскажу дальше. $codes = self::$ErrorCodes; // Функция которая вызывается в случае завершения скрипта!!! Обратите внимание, даже если в процессе работы выскочит критическая ошибка, функция сработает сразу после неё, после чего выполнение скрипта остановится. // Создаем обработчику новую безымянную функцию. // Так-же используем конструкцию "замыкания", берем в область видимости переменных функции 2 новых переменных ($callback и $codes) function() use ($codes,$callback){ // Тут просто надо читать (это место у меня дримвейвер разрисовал красным) - Возможно это даже "костыль" но работает ))) $self = __CLASS__; for($k=0;$k<count($self::$Errors);$k++){ $error = $self::$Errors[$k]; $errno = $error['errno']; $errstr= $error['errstr']; $errfile=$error['errfile']; $errline=$error['errline']; $err = (isset($codes[$errno])) ? $err = $codes[$errno] : $err = 'Unknown '; $callback($errno, $errstr, $errfile, $errline, $codes); } } } ); // Создаем функцию которая реагирует на исключения которые не отловили соответствующей конструкцией set_exception_handler(function($exception){ $self = __CLASS__; $self::$Errors[] = array( 'errno' => 0, 'errstr' => $exception->getMessage(), 'errfile'=> $exception->getFile(), 'errline'=> $exception->getLine(), ); return false; } ); // Создаем функцию которая реагирует на ошибки function(){ $self = __CLASS__; $self::$Errors[] = array( 'errno' => $errno, 'errstr' => $errstr, 'errfile'=> $errfile, 'errline'=> $errline, ); return false; } ); } }
Едем дальше :
index.php :
PHP:
скопировать код в буфер обмена
// Запускаем статический метод класса с аргументом в виде безымянной функции Errors :: Init(function(){ // Собираем аргументы функции в переменные // Переводим код ошибки в читабельный вид (массив с кодами и именами ошибок в классе) $err = (isset($codes[$errno])) ? $codes[$errno] : 'Unknown'; // Тут конструкция которая используется для работы с битовыми операторми, её суть в данном примере это узнать по номеру ошибки какой "тяжести" она является, и если она критическая, после которой работа скрипта остановится мы её обрамляем в тэг <b> чтобы показать какая именно из ошибок привела к таким чудовищным последствиям. Ессно echo ... у меня в коде заменены на логирование ошибок т.к пользователю их видеть не совсем обязательно но для наглядности тут echo. if($errno & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR)) echo "<br><b>$err : $errstr в файле $errfile на строке $errline</b> (работа скрипта остановлена)"; else echo "<br>$err : $errstr в файле $errfile на строке $errline"; } );
ну и для наглядности вызовем парочку :
итак про битовые маски, помните массив из класса?
if( $errno & (E_ERROR | E_CORE) ) // - Если ошибка $errno одна из этих
if( $errno & ( E_ALL ^ E_NOTICE ) ) // - Если любая ошибка кроме NOTICE итд. Подробней ссылки на материалы я указал выше. Отредактировано модератором: Мелкий, 04 Февраля, 2012 - 09:33:49
|