За последние 24 часа нас посетили 56926 программистов и 1795 роботов. Сейчас ищут 942 программиста ...

Механизмы исключений в PHP

Тема в разделе "PHP для новичков", создана пользователем rar, 6 июл 2009.

  1. rar

    rar Активный пользователь

    С нами с:
    9 дек 2008
    Сообщения:
    206
    Симпатии:
    0
    Адрес:
    Москва
    Собственно, так ли они нужны? Давайте поговорим с аргументацией и примерами.
     
  2. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    set_error_handler + trigger_error
     
  3. rar

    rar Активный пользователь

    С нами с:
    9 дек 2008
    Сообщения:
    206
    Симпатии:
    0
    Адрес:
    Москва
    Поясните.
     
  4. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Начинайте.
     
  5. alexeurodnepr

    alexeurodnepr Активный пользователь

    С нами с:
    18 июл 2008
    Сообщения:
    244
    Симпатии:
    0
    Mr.M.I.T.

    может он имел ввиду try,catch,throw?
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    alexeurodnepr
    я знаю что он имел,
    я привёл лучшую альтернативу =)
     
  7. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Приведи аргументы
     
  8. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    ИМХО, если бы механизм исключений в РНР мог отлавливать фатальные ошибки, то это было бы тогда охринительно.
    Но, увы:

    PHP:
    1. <?
    2.  
    3. try {
    4.     UnknownFunction(UnknownArgument);
    5. } catch (Exception $e) {
    6.     if(preg_match('/([a-z_]+?[a-z0-9_]*?\(\))/i', $e->GetMessage(), $functionName)) {
    7.         echo "Function ".$functionName[1]." has not been defined";
    8.     }
    9. }
    10.  
    11. ?>
    Заместо этого мы будем делать вызов фунцкии function_exists.
     
  9. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    куйня :)
     
  10. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    нефига, хотя бы потому что не нужно тыкать везде эти try/catch
     
  11. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    В этом и разница: в случае trigger_error ты можешь отловить ошибку только в handler'е, а в случае использования исключений это можно сделать где-то еще. Т.е. ты можешь не вмешиваясь во внутренний код решить, обработать ошибку и принять меры или забить и пусть handler остановит скрипт.
    Конечно, это можно сделать и используя trigger_error, но тогда нужно будет отлавливать возвращаемый результат и проверять его на ошибку.
    Для примера:
    PHP:
    1.  
    2. <?php
    3. /**
    4.  * @return int кол-во чего-то или -1 если файл не найден, -2 если файл пустой, …
    5.  */
    6. function somefunc() {
    7.    …
    8.    return -1;
    9.    …
    10.    return -2;
    11.    …
    12.    return $n;
    13. }
    14.  
    15. $num = somefunc();
    16. if ($num == -1)
    17.     trigger_error('file not found');
    18. if ($num == -2)
    19.    trigger_error('file is empty');
    20.  
    21. // vs
    22.  
    23. /**
    24.  * @return int …
    25.  */
    26. function secondFunc() {
    27.    …
    28.    throw new ExceptionFileNotFound();
    29.    …
    30.    throw new ExceptionEmptyFile();
    31.    …
    32.    return $n;
    33. }
    34.  
    35. $num = secondFunc();
    36.  
    Другое дело, что большинство не привыкло отлавливать ошибки…
     
  12. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    А зачем? Handler рул.
    PHP:
    1. <?
    2. set_error_handler("Handler");
    3. function Handler($errno,$errstr,$errfile,$errline){
    4.        if(error_reporting()){
    5.           $errors=array(
    6.                 E_ERROR              => 'Error',
    7.                 E_WARNING            => 'Warning',
    8.                 E_PARSE              => 'Parsing Error',
    9.                 E_CORE_ERROR         => 'Core Error',
    10.                 E_CORE_WARNING       => 'Core Warning',
    11.                 E_COMPILE_ERROR      => 'Compile Error',
    12.                 E_COMPILE_WARNING    => 'Compile Warning',
    13.                 E_USER_ERROR         => 'User Error',
    14.                 E_USER_WARNING       => 'User Warning',);
    15.           if(array_key_exists($errno,$errors)){
    16.                die("Тип: ".$errors[$errno]."\r\nТекст: {$errstr}\r\nФайл: {$errfile}\r\nСтрока: {$errline}");
    17.           }
    18.        }
    19. }
    20. function BlaBla(){
    21.  if()
    22.    trigger_error("файл не найден",E_USER_ERROR);
    23.  if()
    24.    trigger_error("чё то там не найден",E_USER_ERROR);
    25. }
    26. ?>
    для этого можно менять ключи в trigger'е
    а в случае с классами, мне нравится делать внутренний Handler и там уже не обязательно trigger
     
  13. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    а я понял о чём ты говоришь, но тогда как быть с фатальными ошибками?
     
  14. shurastik

    shurastik Активный пользователь

    С нами с:
    22 фев 2008
    Сообщения:
    285
    Симпатии:
    0
    Адрес:
    Латвия
    а они никак не ловятся
     
  15. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    я имел ввиду не PHP Fatal Errors а фатальны скриптовые, ну типа не могу прочитать файл и из-за этого теперь не будет работать весь класс
     
  16. shurastik

    shurastik Активный пользователь

    С нами с:
    22 фев 2008
    Сообщения:
    285
    Симпатии:
    0
    Адрес:
    Латвия
    программа, работающая с этим классом ловит исключение и уже решает что дальше делать
     
  17. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    дык в том то и дело, что во первых она может его и не ловить, а во вторых какого фига она будет решать если это фатальная ошибка для этого класса
     
  18. shurastik

    shurastik Активный пользователь

    С нами с:
    22 фев 2008
    Сообщения:
    285
    Симпатии:
    0
    Адрес:
    Латвия
    а это уже не проблемы класса. его дело выкинуть исключение

    исключения ловятся по типу
     
  19. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Если для класса критично, чтобы файл был доступен, то он кидает исключение.
    Как пример с ходу: есть обертка над БД, в ней вызываешь метод «использовать вот эту БД». А БД нет и прав для создания нет. Что класс должен сделать? Кидает исключение.
    А дальше уже включается логика более высокого по уровню логики класса (простите за тавталогию): если без этой БД жить может (есть другая БД или не особо-то и нужные данные), то отлавливает исключение, и работает по запасному варианту.
    А вот если нужна конкретно эта БД, то не ловит исключение, а пропускает его на более высокий уровень и тут опять более высокоуровневый класс может отловить исключение и т.д.
    Наконец, если ошибка неисправима, то вызывается exception handler и в нем уж происходит запись в лог/вывод/отсылка по почте и все такое, включая вывод «сорри, проводятся профилактические работы, зайдите через 5 минут» конечному пользователю)
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    ладно.
    но мне всё равно больше правится для таких вещей делать в классе внутренний ErrorHandler,
    как в DBSimple
     
  21. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Mr.M.I.T., по-моему ты просто фундаментально не понимаешь что такое исключения и что с ErrorHandler они никак не связаны.
     
  22. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    vasa_c
    я пытаюсь не понять, а представить куда бы мне их впихнуть на практике
    а вообще скажи
     
  23. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    По фундаментальному пониманию обычно лучше всех говорит Яндекс: обработка исключений в php.

    PS. И, вуаля, первая же ссылка на меня :)
     
  24. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    vasa_c
    аи аи аи, всё к этому и шло? :)

    Ps/ Не, всё таки я всё правельно с исключениями понял, просто ты не совсем понял меня
     
  25. vasa_c

    vasa_c Активный пользователь

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Тогда объясняю в двух предложениях.

    1-е. Подпрограмма по идее может сделать две вещи: сделать то что от неё хотели (или вернуть результат который просили) или сказать "ой, не могу". Причём говорит "ой, не могу" и дальше её ничего не интересует.

    2-е. Какого е..го х..я, какая-то функция из какой-то сторонней библиотеки из-за того, что она не может что-то там сделать должна убивать весь сценарий?