За последние 24 часа нас посетили 22558 программистов и 1004 робота. Сейчас ищут 670 программистов ...

Ну и в чём гениальность Throwable?

Тема в разделе "PHP для новичков", создана пользователем Вероломство, 4 янв 2021.

Метки:
  1. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    Мне предложили отказаться от set_error_handler(), set_exception_handler(), register_shutdown_function() в пользу Throwable(), КОТОРЫЙ ТИПА ЛОВИТ ВСЁ, тестирую:
    PHP:
    1. <?php
    2.  
    3. use core\Test;
    4.  
    5. chdir(dirname(__DIR__));
    6. spl_autoload_register(function ($class) {
    7.     $file = str_replace('\\', '/', $class) . '.php';
    8.     if (is_file($file)) {
    9.         require_once $file;
    10.     }
    11. });
    12. try {
    13.     new Test(); // class Test{use test;}
    14. } catch (Throwable $throwable) {
    15.     echo 'Ошибка: ' . $throwable->getMessage();
    16. }
    Результат: Fatal error: Trait 'core\test' not found :)

    Как видим НЕ ЛОВИТ ОН ВСЁ и несуществующий трейт, попал в НЕПЕРЕХВАЧЕННУЮ данным интерфейсом фатальную ошибку, которую я лично, ловлю в register_shutdown_function().

    Может я чего-то не понял в Throwable и там есть какой-то секрет для отлова ФАТАЛЬНОЙ ошибки ну вот хотя бы несуществующего трейта? :)
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Такие ошибки перехватываются, насколько я помню, при включении файлов. А вообще, вот именно такие - хай вываливаются фатальными, нафиг их перехватывать? Если я подключил несуществующий трейт, я хочу об этом узнать как можно раньше.
     
    Вероломство нравится это.
  3. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @mkramer, сообщение моё два раза напечаталось я удалил одно, но удалилось два, лень набирать заново, восстановить можно?
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    не успев зайти, как мысль первая прилетела про сравнивание Exception с Throwable ...
    PHP:
    1. try {
    2. // Code that may throw an Exception or Error.
    3. } catch (Throwable $t) {
    4. // Executed only in PHP 7, will not match in PHP 5.x
    5. } catch (Exception $e) {
    6. // Executed only in PHP 5.x, will not be reached in PHP 7
    7. }
    После почитав, понял суть.
    Тут для ознакомления в актуал PHP https://sergeymukhin.com/blog/sovremennaya-obrabotka-oshibok-v-php
     
    Вероломство нравится это.
  5. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @MouseZver, ничего он там нового не написал, если честно, пару дней назад читал зря время потратил, видимо придётся оставить как есть

    PHP:
    1. <?php
    2.  
    3.  
    4. namespace core;
    5.  
    6.  
    7. use Throwable;
    8.  
    9. class Debug
    10. {
    11.     public static function run()
    12.     {
    13.         ob_start();
    14.         set_error_handler([self::class, 'errorHandler']);
    15.         set_exception_handler([self::class, 'exceptionHandler']);
    16.         register_shutdown_function([self::class, 'uncaughtErrorHandler']);
    17.     }
    18.  
    19.     public static function errorHandler($code, $text, $file, $line)
    20.     {
    21.         self::displayError('Ошибка', $code, $text, $file, $line);
    22.     }
    23.  
    24.     private static function displayError($head, $code, $text, $file, $line)
    25.     {
    26.         ob_end_clean();
    27.         if ($code != 404) {
    28.             $code = 500;
    29.         }
    30.         http_response_code($code);
    31.         if (App::$debug) {
    32.             require_once 'app/views/layouts/errors/displayError.php';
    33.         } else {
    34.             self::logError($head, $code, $text, $file, $line);
    35.             require_once "app/views/layouts/errors/{$code}.html";
    36.         }
    37.         die();
    38.     }
    39.  
    40.     private static function logError($head, $code, $text, $file, $line)
    41.     {
    42.         $date = date('d-m-Y');
    43.         $time = date('H:i:s');
    44.         $bash = str_repeat('-', 120);
    45.         $log_text = "[{$time} - {$head}]\nТекст: {$text}\nФайл: {$file}\nСтрока: {$line}\n{$bash}\n";
    46.         $log_file = "tmp/errors/{$code}/{$date}.log";
    47.         error_log($log_text, 3, $log_file);
    48.     }
    49.  
    50.     public static function exceptionHandler(Throwable $e)
    51.     {
    52.         self::displayError('Исключение', $e->getCode(), $e->getMessage(), $e->getFile(), $e->getLine());
    53.     }
    54.  
    55.     public static function uncaughtErrorHandler()
    56.     {
    57.         $e = error_get_last();
    58.         if ($e) {
    59.             self::displayError('Неперехваченная ошибка', $e['type'], $e['message'], $e['file'], $e['line']);
    60.         }
    61.     }
    62. }
    вот так несуществующий трейт тогда попадёт в Неперехваченные и обработается, как ожидалось
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    если желаешь перехватывать ошибки на низком уровне компиляции, то да - set_error_handler не все, но умеет дополнительно кастомизировать ошибки. Я в начале своего пути по php тоже что-то подобное пилил. После осмыслил - а нахрена ?
     
    Вероломство нравится это.
  7. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @MouseZver, set_error_handler не ловит несуществующий трейт - это неперехваченная ошибка, нужно в error_get_last её искать через register_shutdown_function, у меня просто админу и пользователю разные страницы (виды) отдаются при срабатывании глобального обработчика ошибок: админу - трассировка, пользователю - 404

    я просто хотел избавиться от громоздкого дебаггера и сделать всё одним try-catch с помощью Throwable, но вот этот ОДИН неотловленный трей портит мне всё настроение (хотя других пока что косяков в нём не нашёл)
     
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    тобишь у тебя не пишет текст, заданный тобой об таком то ошибке?
    --- Добавлено ---
    Я просто на данный момент знаю, что не все ошибки ловятся и можно на свой лад переделать
     
  9. Вероломство

    Вероломство Активный пользователь

    С нами с:
    19 июн 2017
    Сообщения:
    615
    Симпатии:
    24
    @MouseZver, это не пользовательские исключения, для своих исключения я могу понаделать своих классов, реализующих Throwable и выдавать юзерам всякую ерунду разноцветную с эти текстом, НО мне нужно при глобальном выбросе принять решение кому что показать, Throwable при несуществующем трейте не сделает выброс, нужно error_get_last задействовать и оттуда доставать неперехваченную несуществующего трейта