Гость
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / Обработка исключений в PHP / 24 сообщений из 24, страница 1 из 1
24.08.2019, 12:53
    #39853473
snakenest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
Код: 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
24.08.2019, 20:27
    #39853506
полудух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
на ютубе есть всё
и в гугле тоже
...
Рейтинг: 0 / 0
24.08.2019, 20:46
    #39853510
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
snakenest, а какое исключение вы ждете? в коде нет throw
...
Рейтинг: 0 / 0
25.08.2019, 16:10
    #39853555
Hett
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
Barlonesnakenest, а какое исключение вы ждете? в коде нет throw

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

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

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

Код: 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
26.08.2019, 15:25
    #39853768
полудух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
YouTube Video
...
Рейтинг: 0 / 0
26.08.2019, 15:49
    #39853775
snakenest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
полудух,

это конечно интересно :)
но
Я добавил перехват 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
26.08.2019, 15:51
    #39853776
snakenest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
Или, как перед вызовом

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



проверить есть ли catch?
...
Рейтинг: 0 / 0
26.08.2019, 17:30
    #39853821
полудух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
snakenest, когда ошибка обнаружится (fatal error на почту придёт), вы её исправите и её больше не будет
зачем в коде эксепшн? Он вреден.
...
Рейтинг: 0 / 0
26.08.2019, 17:40
    #39853827
полудух
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
толковые программеры топят против эксепшенов
вот, например, Страуструп:
авторНЕ существует такой тулзы, которая сумеет проследить весь путь ДО исключения и выдать инфу по каждому шагу.
Само исключение НЕ гарантирует корректность данных, они могут придти откуда угодно.
и, например, Ален Голуб (автор "Верёвка достаточной длины, чтобы выстрелить себе в ногу"):
Код: 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
27.08.2019, 10:43
    #39854063
snakenest
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обработка исключений в PHP
полудух....
Я, в своей практике написания нескольких CRM с нуля и кучи всяких скриптов, так и не нашёл, где заюзать исключения.

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

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

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

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

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

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

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

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

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

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

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

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

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


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