Не могу понять set_exception_handler

Обсуждение серверного программирования.

Модераторы: Duncon, Yurich

garmayev
Сообщения: 26
Зарегистрирован: 19 дек 2013, 17:40
Откуда: Irkutsk
Контактная информация:

30 май 2017, 14:14

имеется кусок кода:

Код: Выделить всё

set_exception_handler("ExceptionHandler");

function ExceptionHandler( $e ) {
    error_log( $e->getMessage, $e->getFile, $e->getLine );
}

spl_autoload_register( function ($className) {
    $data['template'] = "default";
    $lowClassName = strtolower($className);
    if (file_exists('classes/'.$lowClassName.'.php')) {
        require('classes/'.$lowClassName.'.php');
    } else {
        throw new Exception("Error Loading Classfile $className", 1);
    }
} );
 
Как я понимаю, функция set_exception_handler устанавливает новый обработчик исключений, которые появляются ПОСЛЕ его установки.

В данном случае если из файла index.php попробовать загрузить класс SERTIAKS: :D SAD() /* Класс чисто для примера, набрал его наобум */, логгирования не происходит (), хотя если в конец кода вставить дополнительно throw new Exception("test exception");, то все отрабатывает как надо...

Что я делаю не так?
Аватара пользователя
Duncon
Сообщения: 1974
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

30 май 2017, 16:01

echo 'вызов дошёл'; просто пропиши чтоб посмотреть доходит ли вызов и до какого места.. Попробуй отдельно register функцию прописать, возможно динамическую разваливает просто..
[syntax=Delphi] [/syntax]
garmayev
Сообщения: 26
Зарегистрирован: 19 дек 2013, 17:40
Откуда: Irkutsk
Контактная информация:

30 май 2017, 16:35

Duncon писал(а):Попробуй отдельно register функцию прописать, возможно динамическую разваливает просто..

Вот тут можно чуток подробнее? если вы говорите про функцию register_tick_function то я не совсем понимаю как ее использовать?

По поводу первого пункта модифицировал код то такого состояния:

Код: Выделить всё

    set_exception_handler("ExceptionHandler");

    function ExceptionHandler( $e ) {
        echo 'ExceptionHandler
';
        error_log( $e->getMessage().' in file '.$e->getFile().' in line '.$e->getLine() );
        require ('classes/error.php');
        Error::error404( array('template'=>'default', 'message'=>$e->getMessage() ) );
    }

    spl_autoload_register( function ($className) {
        $data['template'] = "default";
        $lowClassName = strtolower($className);
        if (file_exists('classes/'.$lowClassName.'.php')) {
            require('classes/'.$lowClassName.'.php');
        } else {
            echo 'failed autoloader
';
            throw new Exception("Error Loading Classfile $className", 1);
        }
    } );
 
В ответ получаю на странице
failed autoloader
Error Loading Classfile SERTIAKS
Аватара пользователя
Duncon
Сообщения: 1974
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

30 май 2017, 17:59

[syntax=php]
function my_autoloader($className) {
$data['template'] = "default";
$lowClassName = strtolower($className);
if (file_exists('classes/'.$lowClassName.'.php')) {
require('classes/'.$lowClassName.'.php');
} else {
echo 'failed autoloader
';
throw new Exception("Error Loading Classfile $className", 1);
}
}
spl_autoload_register('my_autoloader');
[/syntax]
[syntax=Delphi] [/syntax]
garmayev
Сообщения: 26
Зарегистрирован: 19 дек 2013, 17:40
Откуда: Irkutsk
Контактная информация:

30 май 2017, 18:12

Duncon писал(а):[syntax=php]
function my_autoloader($className) {
$data['template'] = "default";
$lowClassName = strtolower($className);
if (file_exists('classes/'.$lowClassName.'.php')) {
require('classes/'.$lowClassName.'.php');
} else {
echo 'failed autoloader
';
throw new Exception("Error Loading Classfile $className", 1);
}
}
spl_autoload_register('my_autoloader');
[/syntax]

то же самое. Никаких изменений на выхлопе нет.
т.е. автолоад сам по себе работает нормально. Меня волнует проблема с исключением. Почему ф-ия ExceptionHandler срабатывает странным образом - из функции my_autoloader логи/эхо не пишутся, а если прописать напрямую в конец этого файла вызов исключения, то все пишется так, как нужно, и эхо, и логи
Аватара пользователя
Duncon
Сообщения: 1974
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

30 май 2017, 20:20

В мануле написано, что поcле вызова выполнение будет остановлено.. Может через set_error_handler решать эту задачу. К томуж зачем вызывать исключения? Если можно просто error_log('Класс не загрузился '.$className); прописать? Зачем вообще писать в лог, о том что класс не загрузился? Несколько дней и файл будет весить от пары метров до несколько гигов при активном пользовании..
[syntax=Delphi] [/syntax]
garmayev
Сообщения: 26
Зарегистрирован: 19 дек 2013, 17:40
Откуда: Irkutsk
Контактная информация:

31 май 2017, 02:50

Duncon писал(а):К томуж зачем вызывать исключения? Если можно просто error_log('Класс не загрузился '.$className); прописать?
Может я не прав, но мне кажется, что наиболее правильной будет обработка важных моментов работы системы через оператор

Код: Выделить всё

try {
// Some code
} catch ( Exception $e ) {
// Some code
}. 
Duncon писал(а):Зачем вообще писать в лог
По моей задумке, должна выводится специальная страница с ошибкой (без участия htaccess), сформироваться письмо администратору сайта со всеми необходимыми переменными, которые привели к краху системы. Лог - это чисто на стадии разработки. В ситуации проблема с собственной обработкой исключения
Duncon писал(а):Несколько дней и файл будет весить от пары метров до несколько гигов при активном пользовании..
система пишется не для заказчика, а для себя. Отсюда желание вести полный контроль и максимально исключить непредвиденные ошибки
Duncon писал(а):В мануле написано, что поcле вызова выполнение будет остановлено..
После выброса исключения? Но ведь как раз для этого и была введена эта функция, не? Для обработки этого исключения.
garmayev
Сообщения: 26
Зарегистрирован: 19 дек 2013, 17:40
Откуда: Irkutsk
Контактная информация:

31 май 2017, 03:00

Так и не понял в чем проблема, но только что система заработала так, как я этого добивался уже несколько дней...
Алиса(Алиса_в_стране_чудес) писал(а):Все становится чудесатее и чудесатее...
Последние действия:
1. Вынес обработку исключения в индексный файл
2. Перезагрузил страницу - Работает
3. вернул обработку на СТАРОЕ место
4. Перезагрузил страницу - РАБОТАЕТ!

осталось только понять в чем была ситуевина...
Аватара пользователя
Duncon
Сообщения: 1974
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

31 май 2017, 12:31

try { } catch - вообще не использую, не вижу смысла. В системном программировании он есть..
Пойми php имеет нормальную встроенную систему ошибок, он сам пишет в файл с указанием конкретной строчки кода в файле, от куда произошла ошибка.. В местах где сам обрабатываешь пишешь просто error_log('Произошла ошибка такая-то, вот запрос вызвавший ошибку..'); Под твою задачу остаётся только поставить робота который будет периодически находить error_log в папках на сервере и отсылать письмо счастья, дальше включай воображение - можно целиком отослать, можно обработать как тебе удобней.. По факту отдельную систему обработки ошибок обычно не делают (редко встречается). И это лишняя нагрузка на сервер.. Проще код нормально написать без ошибок.. Стоит опасаться ошибок не в коде, а в логике программ, они куда серьёзнее и не регистрируются как ошибки..

Мануал почитай внимательно, функций обработки ошибок несколько, выбирай исходя из своих задумок.. В повседневной жизни использую наверное <5% от возможностей php и это даёт мне возможность решать 100% задач, в дебри типа перебинживания ошибок вообще не лезу..
[syntax=Delphi] [/syntax]
Аватара пользователя
AiK
Сообщения: 2274
Зарегистрирован: 13 фев 2004, 18:14
Откуда: СПб
Контактная информация:

31 май 2017, 13:00

try { } catch - вообще не использую, не вижу смысла.
Смысл простой - продолжение работы скрипта при возникновении критической ошибки.

А перехват ошибок нужен, чтобы выводить на экран уведомление об ошибке, но при этом не вываливать на всеобщее обозрение потенциально чувствительную информацию. Вроде имени БД или пути до файла с шаблоном.
Даже самый дурацкий замысел можно воплотить мастерски
Ответить