powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Обработка исключений в PHP
24 сообщений из 24, страница 1 из 1
Обработка исключений в PHP
    #39853473
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
function ErrorCatcher($errno, $errmsg, $filename, $linenum, $errcontext)
{
    if (is_array($errcontext))
     {
       echo 'err: ('.$errno.')'.$errmsg.' in '.$filename.' at '.$linenum.print_r($errcontext,true)."<br>";
     }
    else
     {
       echo 'err: ('.$errno.')'.$errmsg.' in '.$filename.' at '.$linenum."<br>";  
     }
   return true;  
}

set_error_handler('ErrorCatcher');

$r=0;
try
 {
     $t=20/0;
     $r=1;
 }
 catch (Exception $e)
 {
     $r=3;
     echo "<pre>".print_r($e)."</pre>";
 }

echo "test finish r=".$r;




При ошибке срабатывает вызов ErrorCatcher, и далее идет выполнение кода как ни в чем не бывало.
Подскажите, как в представленном примере одновременно использовать и ErrorCatcher и обрабатывать ошибку в блоке try catch
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853506
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
на ютубе есть всё
и в гугле тоже
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853510
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snakenest, а какое исключение вы ждете? в коде нет throw
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853555
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlonesnakenest, а какое исключение вы ждете? в коде нет throw

DivisionByZero, по всей видимости.
Только вот в PHP кроме как Exception и RuntimeException есть еще и Error. В итоге имеем три базовых класса от которых могут быть наследованны исключения. У вас перехватывается только одно из них. А деление на 0 бросает исключение унаследованное от Error.
Чтобы ловило все, используйте Throwable.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853652
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettBarlonesnakenest, а какое исключение вы ждете? в коде нет throw

DivisionByZero, по всей видимости.
Только вот в PHP кроме как Exception и RuntimeException есть еще и Error. В итоге имеем три базовых класса от которых могут быть наследованны исключения. У вас перехватывается только одно из них. А деление на 0 бросает исключение унаследованное от Error.
Чтобы ловило все, используйте Throwable.А, вот оно как сейчас. Во времена РНР 5.х чтобы ошибки превратить в исключения, надо было написать что-то вроде
Код: php
1.
2.
3.
4.
    function exceptionErrorHandler($errNumber, $errStr, $errFile, $errLine ) {
        throw new ErrorException($errStr, 0, $errNumber, $errFile, $errLine);
    }
    set_error_handler('exceptionErrorHandler');
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853658
konstantin_got
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HettBarlonesnakenest, а какое исключение вы ждете? в коде нет throw

DivisionByZero, по всей видимости.
Только вот в PHP кроме как Exception и RuntimeException есть еще и Error. В итоге имеем три базовых класса от которых могут быть наследованны исключения. У вас перехватывается только одно из них. А деление на 0 бросает исключение унаследованное от Error.
Чтобы ловило все, используйте Throwable.

Согласен
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853756
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Путем проб и ошибок, и прочитав горы мусора в гуглах, дотестировался до такой вот весчи!

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
function ErrorCatcher($errno, $errmsg, $filename, $linenum, $errcontext)
{
    echo "error catcher<br>";
    if (is_array($errcontext))
     {
       echo 'err: ('.$errno.')'.$errmsg.' in '.$filename.' at '.$linenum.print_r($errcontext,true)."<br>";
     }
    else
     {
       echo 'err: ('.$errno.')'.$errmsg.' in '.$filename.' at '.$linenum."<br>";  
     }
   
   restore_error_handler();
   trigger_error($errmsg,E_USER_ERROR);
   set_error_handler('ErrorCatcher');
   throw new Exception('test exception');  
   return true;  
}


set_error_handler('ErrorCatcher');

$r=0;
try
 {
     $t=20/0;
     $r=1;
 }
 catch (Exception $e)
 {
     $r=3;
     echo "<br><pre>".print_r($e->getMessage(),true)."</pre><br>";
 }

echo "test finish r=".$r;



в итоге, при ошибке вызывается ErrorCatcher, который выводит текст ошибки -> восстанавливает предыдущий обработчик -> передает ему ошибку -> генерирует исключение.

Но если добавить в конце :
Код: php
1.
2.
3.
$ttt=22/0;

echo "test 2";


то вываливается
Fatal error: Uncaught exception 'Exception' with message 'test exception' in ... и т.д.

Есть ли способ обойти такую Fatal error ? т.е. вызвать исключение, но без обязательного обработчика catch ?
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853768
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YouTube Video
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853775
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
полудух,

это конечно интересно :)
но
Я добавил перехват exception
Код: php
1.
2.
3.
4.
5.
6.
7.
function exception_handler($exception) {
  echo "<br>unhandled exception: " , $exception->getMessage(), "<br>";
  
}

set_error_handler('ErrorCatcher');
set_exception_handler('exception_handler');



теперь не ругается так жестко :)

т.е. когда установлен блок try catch, то exception обрабатывается и скрипт выполняется дальше. Если такого блока нет, то вызывается exception_handler, и скрипт останавливается....

Вопрос. обработчик срабатывает и останавливает выполнение скрипта.
Как при вызове такого обработчика exception продолжить выполнение скрипта?
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853776
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Или, как перед вызовом

Код: php
1.
throw new Exception('test exception');



проверить есть ли catch?
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853821
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snakenest, когда ошибка обнаружится (fatal error на почту придёт), вы её исправите и её больше не будет
зачем в коде эксепшн? Он вреден.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39853827
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
толковые программеры топят против эксепшенов
вот, например, Страуструп:
авторНЕ существует такой тулзы, которая сумеет проследить весь путь ДО исключения и выдать инфу по каждому шагу.
Само исключение НЕ гарантирует корректность данных, они могут придти откуда угодно.
и, например, Ален Голуб (автор "Верёвка достаточной длины, чтобы выстрелить себе в ногу"):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
Итак, что же плохого в исключениях? На самом деле существует две проблемы. Первой является
читаемость. Вам будет тяжело меня убедить, что:

        some_class obj;
        try
        {
                 obj.f();
        }
        catch( some_class::error &r )
        {
                 // выполнить действие в случае ошибки
        }

лучше читается, чем:

        if( obj.f() == ERROR )
                  // выполнить действие в случае ошибки

В любом случае, если try-блок содержит более одного вызова функций, вы не сможете просто
исправить ошибку, потому что вы не сможете узнать, где возникла ошибка.

Следующий пример демонстрирует вторую проблему. Класс CFile, реализующий основной
ввод/вывод двоичных файлов, возбуждает исключение в случае переполнения диска при записи, чего
легко добиться на дискете. Более того, функция write() не возвращает никакого кода ошибки.
Перехват исключения является единственным способом обнаружения ошибки. Вот пример того, как
вы должны обнаруживать ошибку чтения:

char    data[128];
Cfile   f( "some_file", CFile::modeRead );

try
{
        f.Write( data, sizeof(data) );
}
catch( CFileException &r )
{
        if( r.m_cause == CfileException::diskFull )
                 // что-то сделать
}

Имеется две проблемы. Первая явно связана с уродливостью этого кода. Я бы гораздо охотнее
написал:
        bytes_written = f.Write( data, sizeof(data));
         if( bytes_written != sizeof(data) )
                 // разобраться с этим

Вторая проблема одновременно более тонкая и более серьезная. Вы не сможете исправить эту
ошибку. Во-первых, вы не знаете, сколько байтов было записано перед тем, как диск переполнился.
Если Write() возвратила это число, то вы можете предложить пользователю сменить диск, удалить
несколько ненужных файлов или сделать еще что-нибудь для освобождения места на диске. Вы не
можете тут сделать это, потому что не знаете, какая часть буфера уже записана, поэтому вы не знаете,
откуда начинать запись на новый диск.

Даже когда Write() возвратила количество записанных байтов, то вы все еще не можете исправить
ошибку. Например, даже если функцию CFile переписать, как показано ниже, то она все равно не
будет работать:

        char     data[128];
        CFile   f( "some_file", CFile::modeRead );
       int bytes_written;

       try
       {
               bytes_written = f.Write( data, sizeof(data) );
       }
       catch( CFileException &r )
       {
               if( r.m_cause == CFileException::diskFull )
                        // что-то выполнить.

                // при этом переменная bytes_written содержит мусор.
       }

Управление передается прямо откуда-то изнутри Write() в обработчик catch при возбуждении
исключения, перескакивая через все операторы return внутри Write(), а также через оператор
присваивания в вызывающейся функции; переменная bytes_written остается неинициализированной.
Я думаю, что вы могли бы передать Write() указатель на переменную, которую она могла
использовать для хранения числа записанных байтов перед тем, как выбросить исключение, но это не
будет значительным улучшением. Лучшим решением будет отказ от возбуждения исключения и
возврат или числа записанных байтов, или какого-то эквивалента индикатора ошибки.

Последней проблемой являются непроизводительные затраты. Обработка исключения вызывает
очень большие непроизводительные затраты, выражающиеся в возрастании в несколько раз размера
кода и времени выполнения. Это происходит даже в операционных системах типа Microsoft NT,
которая поддерживает обработку исключений на уровне операционной системы. Вы можете
рассчитывать на 10-20% увеличение размера кода и падение скорости выполнения на несколько
процентов при интенсивном использовании исключений.14 Следовательно, исключения должны
использоваться лишь тогда, когда непроизводительные затраты не берутся в расчет, обычно при
наличии возможности лучше предпочесть возврат ошибки.


Я, в своей практике написания нескольких CRM с нуля и кучи всяких скриптов, так и не нашёл, где заюзать исключения.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39854063
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
полудух....
Я, в своей практике написания нескольких CRM с нуля и кучи всяких скриптов, так и не нашёл, где заюзать исключения.

Мне необходимо обработать исключение для отлавливания deadlock при работе с БД, т.к. простой if не поможет. При выполнении запроса может возникнуть не только deadlock, а целый ряд ошибок (как не "бей по рукам" пользователя, но данные он может внести некорректные).
Но учитывая что для всего проекта есть перехватчик ошибок, в целях логирования информации и дальнейшего разбора полетов, хотелось внести в него вызов исключения (дабы инкапсулировать обработку ошибок в одном месте). А как получается, что вызов эксепшена без catch приводит к фатальной ошибке работы скрипта и останавливает его работу, тоесть использовать данный вызов в рамках общей обработки ошибок не получится.

Почему я и спрашиваю, возможно ли както определить, а есть ли catch который должен обработать эксепшн? тогда логика работы общего модуля контроля ошибок проста: ловим ошибку, и если есть catch, то вызываем эксепшн, если нет то идем дальше.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39854127
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухтолковые программеры топят против эксепшенов

у нас некоторые за плоскую зеплю топят и за отказ от прививок.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39854215
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snakenest, если у вас юзер может дедлокнуть БД, вам не об эксепшенах надо думать...
переделывайте.
ввод юзера надо проверять ДО контакта с БД
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855167
snakenest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
полудухsnakenest, если у вас юзер может дедлокнуть БД, вам не об эксепшенах надо думать...
переделывайте.
ввод юзера надо проверять ДО контакта с БД

Юзер - образно, автомат (не на строне моего сервера и приложения) присылает данные одномоментно, в том числе и одинаковые. т.е. данные записи могут обновляться одновременно, что и вызывает deadlock, и повлиять на это я ни как не могу, только обработать исключение и отправить запрос в БД еще раз.

ввод юзера проверяется, но опять таки, есть часть данных присылаемая сервисами, а функции 100% распознавания кодировки текста не существует, отсюда опять обработка исключения.

так что ситуации бывают разные,
полудух... вам не об эксепшенах надо думать...
переделывайте.

иногда переделать просто невозможно :)
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855314
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так проверьте перед записью - установлен лок или нет
или САМИ ставьте глобальный флаг, когда туда пишут, и проверяйте его
snakenestиногда переделать просто невозможно :)
отмазки.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855384
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На каждую обновляемую в субд запись ставить лок? Или может поредложишь всю таблицу локнуть?
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855402
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тут вопрос, откуда вообще взялась задача - локать
если там надо следить, чтобы одну и ту же форму не сохранили 2 разных человека, то да - надо флаг ставить (временный) на каждую такую редакцию
и проверять (через JS), что там всё ещё редактируют
а когда один сохранит, то другому давать инфу, что "данные изменились, форму надо обновить"
решений в гугле есть
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855442
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если это не форма, а api куда летят несколько тысяч rps от одного клиента, что там в гугле по этому кейсу говорят?
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855443
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
* клиент не один, естественно.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855739
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hettapi куда летят несколько тысяч rps от одного клиента
это стандартная ситуация для любого сервера

надо ситуацию конкретно описывать, а не общими категориями рассуждать
ну и что что летят? Проблема то возникает, когда они летят именно в форму, которую нельзя одновременно двум редактировать.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855992
Фотография Hett
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудухHettapi куда летят несколько тысяч rps от одного клиента
это стандартная ситуация для любого сервера

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

Постойкте, какие "формы"... это понятие к HTML относится и бэкэнд может про них ничего не знать. И понятия "редкатировать форму" тоже на бэкэнде не существует. Есть запрос, есть пейлоад и никаких форм. Хватит корчить из себя профи.
...
Рейтинг: 0 / 0
Обработка исключений в PHP
    #39855994
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"бэкенд" (процессор) вообще ничего не знает, кроме 0/1
хватит корчить из себя демагога.
Когда юзер шлёт данные в API, это просто блок данных, который сразу же и пишется.
Какие вы там проблемы нашли? Один записал мгновенно, второй в этот момент только собирается слать.
Перед отправкой проверяется - не изменились ли данные (если там такая ситуация в принципе возможна).
А иначе там нет коллизий в принципе!

Мы обсуждаем именно проблему , когда 2 юзера ОДНОВРЕМЕННО залезли редактировать одинаковые данные, и когда один сохраняет, то у другого остаётся форма со старыми данными, которую НЕЛЬЗЯ сохранять в устаревшем виде.

Не можете уловить суть, покатились в хамство - классика

Ступайте, больше нет желания что-то вам объяснять.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Обработка исключений в PHP
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]