phpist

Untitled

Oct 27th, 2019
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.47 KB | None | 0 0
  1.  
  2.  
  3.  
  4.  
  5. вывелось такое
  6.  
  7. Перехвачена ошибка!
  8. E_USER_ERROR: Damn it! in /var/www/php.xxx/except/w2e_hier.php:9
  9. Stack trace:
  10. #0 [internal function]: PHP_Exceptionizer_Catcher->handler(256, 'Damn it!', '/var/www/php.xx...', 9, Array)
  11. #1 /var/www/php.xxx/except/w2e_hier.php(9): trigger_error('Damn it!', 256)
  12. #2 /var/www/php.xxx/except/w2e_hier.php(3): suffer()
  13. #3 {main}
  14.  
  15. Листинг 26.20. Преобразование ошибок в исключения. Файл w2e_simple.php
  16.  
  17. <?php ## Иерархия ошибок.
  18.  require_once "PHP/Exceptionizer.php";
  19.   suffer();
  20.   function suffer()
  21.   {
  22.     $w2e = new PHP_Exceptionizer(E_ALL);
  23.     try {
  24.       // Генерируем ошибку.
  25.       trigger_error("Damn it!", E_USER_ERROR);
  26.     } catch (AboveE_USER_WARNING $e) {
  27.       // Перехват ошибок: E_USER_WARNING и более серьезных.
  28.       echo "<pre><b>Перехвачена ошибка!</b>\n", $e, "</pre>";
  29.     }
  30.   }
  31. ?>
  32.  
  33.  
  34. Exceptionizer.php
  35.  
  36. <?php ## Класс для преобразования ошибок PHP в исключения.
  37. /**
  38.  * Класс для преобразования перехватываемых (см. set_error_handler())
  39.  * ошибок и предупреждений PHP в исключения.
  40.  *
  41.  * Следующие типы ошибок, хотя и поддерживаются формально, не могут
  42.  * быть перехвачены:
  43.  * E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR,
  44.  * E_COMPILE_WARNING
  45.  */
  46. class PHP_Exceptionizer
  47. {
  48.   // Создает новый объект-перехватчик и подключает его к стеку
  49.   // обработчиков ошибок PHP (используется идеология "выделение
  50.   // ресурса есть инициализация").
  51.   public function __construct($mask = E_ALL, $ignoreOther = false)
  52.   {
  53.     $catcher = new PHP_Exceptionizer_Catcher();
  54.     $catcher->mask = $mask;
  55.     $catcher->ignoreOther = $ignoreOther;
  56.     $catcher->prevHdl = set_error_handler(array($catcher, "handler"));
  57.   }
  58.   // Вызывается при уничтожении объекта-перехватчика (например,
  59.   // при выходе его из области видимости функции). Восстанавливает
  60.   // предыдущий обработчик ошибок.
  61.   public function __destruct()
  62.   {
  63.     restore_error_handler();
  64.   }
  65. }
  66.  
  67. /**
  68.  * Внутренний класс, содержащий метод перехвата ошибок.
  69.  * Мы не можем использовать для этой же цели непосредственно $this
  70.  * (класса PHP_Exceptionizer): вызов set_error_handler() увеличивает
  71.  * счетчик ссылок на объект, а он должен остаться неизменным, чтобы в
  72.  * программе всегда оставалась ровно одна ссылка.
  73.  */
  74. class PHP_Exceptionizer_Catcher
  75. {
  76.   // Битовые флаги предупреждений, которые будут перехватываться.
  77.   public $mask = E_ALL;
  78.   // Признак, нужно ли игнорировать остальные типы ошибок, или же
  79.   // следует использовать стандартный механизм обработки PHP.
  80.   public $ignoreOther = false;
  81.   // Предыдущий обработчик ошибок.
  82.   public $prevHdl = null;
  83.   // Функция-обработчик ошибок PHP.
  84.   public function handler($errno, $errstr, $errfile, $errline)
  85.   {
  86.     // Если error_reporting нулевой, значит, использован оператор @,
  87.     // и все ошибки должны игнорироваться.
  88.     if (!error_reporting()) return;
  89.     // Перехватчик НЕ должен обрабатывать этот тип ошибки?
  90.     if (!($errno & $this->mask)) {
  91.       // Если ошибку НЕ следует игнорировать...
  92.       if (!$this->ignoreOther) {
  93.         if ($this->prevHdl) {
  94.           // Если предыдущий обработчик существует, вызываем его.
  95.           $args = func_get_args();
  96.           call_user_func_array($this->prevHdl, $args);
  97.         } else {
  98.           // Иначе возвращаем false, что вызывает запуск встроенного
  99.           // обработчика PHP.
  100.           return false;
  101.         }
  102.       }
  103.       // Возвращаем true (все сделано).
  104.       return true;
  105.     }
  106.     // Получаем текстовое представление типа ошибки.
  107.     $types = array(
  108.       "E_ERROR", "E_WARNING", "E_PARSE", "E_NOTICE", "E_CORE_ERROR",
  109.       "E_CORE_WARNING", "E_COMPILE_ERROR", "E_COMPILE_WARNING",
  110.       "E_USER_ERROR", "E_USER_WARNING", "E_USER_NOTICE", "E_STRICT",
  111.     );
  112.     // Формируем имя класса-исключения в зависимости от типа ошибки.
  113.     $className = __CLASS__ . "_" . "Exception";
  114.     foreach ($types as $t) {
  115.       $e = constant($t);
  116.       if ($errno & $e) {
  117.         $className = $t;
  118.         break;
  119.       }
  120.     }
  121.     // Генерируем исключение нужного типа.
  122.     throw new $className($errno, $errstr, $errfile, $errline);
  123.   }
  124. }
  125.  
  126. /**
  127.  * Базовый класс для всех исключений, полученных в результате ошибки PHP.
  128.  */
  129. abstract class PHP_Exceptionizer_Exception extends Exception
  130. {
  131.   public function __construct($no = 0, $str = null, $file = null, $line = 0) {
  132.     parent::__construct($str, $no);
  133.     $this->file = $file;
  134.     $this->line = $line;
  135.   }
  136. }
  137.  
  138. /**
  139.  * Создаем иерархию "серьезности" ошибок, чтобы можно было
  140.  * ловить не только исключения с указанием точного типа, но
  141.  * и сообщения, не менее "фатальные", чем указано.
  142.  */
  143. class E_EXCEPTION extends PHP_Exceptionizer_Exception {}
  144.   class AboveE_STRICT extends E_EXCEPTION {}
  145.     class E_STRICT extends AboveE_STRICT {}
  146.     class AboveE_NOTICE extends AboveE_STRICT {}
  147.       class E_NOTICE extends AboveE_NOTICE {}
  148.       class AboveE_WARNING extends AboveE_NOTICE {}
  149.         class E_WARNING extends AboveE_WARNING {}
  150.         class AboveE_PARSE extends AboveE_WARNING {}
  151.           class E_PARSE extends AboveE_PARSE {}
  152.           class AboveE_ERROR extends AboveE_PARSE {}
  153.             class E_ERROR extends AboveE_ERROR {}
  154.             class E_CORE_ERROR extends AboveE_ERROR {}
  155.             class E_CORE_WARNING extends AboveE_ERROR {}
  156.             class E_COMPILE_ERROR extends AboveE_ERROR {}
  157.             class E_COMPILE_WARNING extends AboveE_ERROR {}
  158.   class AboveE_USER_NOTICE extends E_EXCEPTION {}
  159.     class E_USER_NOTICE extends AboveE_USER_NOTICE {}
  160.     class AboveE_USER_WARNING extends AboveE_USER_NOTICE {}
  161.       class E_USER_WARNING extends AboveE_USER_WARNING {}
  162.       class AboveE_USER_ERROR extends AboveE_USER_WARNING {}
  163.         class E_USER_ERROR extends AboveE_USER_ERROR {}
  164.   // Иерархии пользовательских и встроенных ошибок не сравнимы,
  165.   // т.к. они используются для разных целей, и оценить
  166.   // "серьезность" нельзя.
  167. ?>
Advertisement
Add Comment
Please, Sign In to add comment