За последние 24 часа нас посетили 57977 программистов и 1845 роботов. Сейчас ищут 1109 программистов ...

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

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

  1. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    vasa_c
    вот вот, ты точно меня не понял
    1. Да
    2. В том то и дело, что с Хэндлером ничего не убивается, точнее сам пользователь программы решает убивать или нет.

    Я предложил 2 альтернативы, на мой взгляд лучшие:
    первое, сторонней библиотеке выдвать трригер со своим ключём trigger_error("",MY_KEY);
    и второй, мне больше всего нравится, сделать внутренний Handler, короче юзверь сам устанавливает обратную функцию для вывода ошибки

    А лучше они тем, что не нужно везде тыкать тру и катч
     
  2. AlexGousev

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

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Mr.M.I.T.
    т.е. ты предлагаешь перед каждым вызовом каждого метода делать установку специального хэндлера для именно этого метода этого класса, а после вызова возвращаться к стандартному? И это проще, чем try?
    А как вернуть логику из хэндлера в точку выполения сразу за вызовом да чтобы еще было понятно, произошла ошибка или нет?

    Хочется увидеть реализацию без эксепшенов вот такого, например, куска (загрузка неких данных из неких файлов, если они есть):
    PHP:
    1. <?php
    2. try {
    3.    $data->readFrom('one.dat');
    4.    $data->readFrom('second.dat');
    5.    $data->readFrom('third.dat');
    6. }
    7. catch (DataException $e) {}
    8.  
     
  3. vasa_c

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

    С нами с:
    22 мар 2006
    Сообщения:
    1.760
    Симпатии:
    0
    Адрес:
    гор.Ленинград
    Тру и катч нужно тыкать не везде, а там где это нужно. Можно нигде. Можно один раз на всё программу.

    Т.е. сторонняя библиотека должна знать о том, что в системе в которую её внедряют реализована вот такая вот хитропопая вещь с trigger_error?

    Исключительная ситуация это далеко не всегда ошибка и далеко не всегда её следует обрабатывать путём вывода чего-то.
     
  4. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    не не не
    перед вызовом класса, один раз, где-нибудь при инициализации
    я начинал говорить про фатальные
    зачем? если нет в системе такой хитропопой вещи, она просто будет делать дефолтную обработку ошибки своим алгоритмом
     
  5. Mr.M.I.T.

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

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вообще я предлогаю комбинировать
    для фатальных юзать каллбэк
    для нотисных исключения, хотя опять таки, мне удобно в этом случае просто возвращать false напрмер, таким образом, я их не использую вообще.
     
  6. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    кстати вопрос:
    есть у меня место в методе, где может произойти что-то такое, ...
    а) после чего его работу стоит прекратить и сообщить классу выше информацию об ошибке (бросаем исключение)
    б) все прошло гладко, ничего делать не нужно
    в) что-то пошло не так, но ошибка как бы не критическая. Нужно продолжить работу, но сообщить классу выше что не все спокойно в королевстве Датском.

    Что предложите по пункту "в"?
     
  7. Apple

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

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    А этот случай даже теоретически не предназначен для исключений =)
    Можно для этого сделать или вложенный блок, или сделать вызов внешнего метода.
    Такие случаи и в других языках не ловятся с помощью try/catch/finally.
     
  8. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    так я как бе не намекаю на ущербность пыха, мне интересно как поступать в таких случаях. Да, такой ситуевины еще не было, но мне интересно. Пока как вариант можно хранить ошибки внутри в переменной а потом смотреть какого они типа и выплескивать из.
     
  9. Apple

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

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Ну вообще, тут можно сделать set_error_handler для warning или notice, а остальные ловить :)
     
  10. iliavlad

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

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    Функция может сделать, то что от нее хотят, а может не сделать. Быть слегка беременной не получится)
     
  11. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Koc
    А можешь дать пример на вариант в)?

    Хотя кажется придумал:
    Надо получить некоторые данные из БД. Если не получается, то подгрузить данные из файла и проинформировать пользователя, что это может быть не самая последняя версия данных.

    Наверное вместе с данными придется возвращать некий код:
    -1 - ошибка (можно не возвращать, а выбрасывать исключение)
    0 - данные из БД
    1 - данные из файла
     
  12. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    еще такой вариант:
    PHP:
    1. <?
    2. try {
    3.     // получить данные из БД
    4. } catch DBEsception $e {
    5.     // получить из файла
    6.     // если совсем хреново - файла нет
    7.     throw new ClassFileException();
    8.     // все не так уж плохо, файл есть, но нужно уведомить о том, что база недоступна
    9.     throw new ClassDBException();
    10. }
    11.  
    и в классе выше ловим по типам
     
  13. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Koc
    А данные из файла отдать?
     
  14. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    блин. Затупил. Тогда только возвращать массивом data, status

    или передавать в метод какую-то переменную, в которой будет результат потом
     
  15. shurastik

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

    С нами с:
    22 фев 2008
    Сообщения:
    285
    Симпатии:
    0
    Адрес:
    Латвия
    кажется, класс на себя много берёт. ИМХО, должно быть два: один работает с БД, второй с файлами:

    PHP:
    1.  
    2. <?php
    3. $message = $data = null;
    4. try {
    5.    $data = $db->getData();
    6. } catch (DbException $e) {
    7.    $message = $e->getMessage();
    8.    try {
    9.       $data = $files->getData();
    10.    } catch (FilesException $fe) {
    11.       throw new FatalException('Жопа');
    12.    }
    13. }
    14. ?>
    15.  
     
  16. Volt(220)

    Volt(220) Активный пользователь

    С нами с:
    11 июн 2009
    Сообщения:
    1.640
    Симпатии:
    1
    Это вы описали функцию getData из моего примера.

    HTML:
    1. <!--первая страница (index.php)-->
    2. <h1>Нажми кнопку и получи данные</h1>
    3. <form method="post" action="main.php">
    4. <p><input type="text" name="cat"></p>
    5. <p><input type="submit" value="Дай данные"></p>
    6. </form>
    7.  
    PHP:
    1. <?php
    2. //то что в примере названо main
    3. $cat=$_POST["cat"];
    4. if (checkCat($cat)){
    5.     list($data,$err)=getData($cat);
    6. }
    7. echo "<pre>$data</pre>";
    8.  
    9. //собственно функция getData, которая должна вернуть данные и сообщить что не все гладко.
    10. function getData($cat){
    11. message = $data = null;
    12. try {
    13.     $data = $db->getData();
    14.     } catch (DbException $e) {
    15.         $message = $e->getMessage();
    16.     try {
    17.         $data = $files->getData();
    18.     } catch (FilesException $fe) {
    19.         throw new FatalException('Жопа');
    20.     }
    21. return array($data,$message;)
    22. }
    23. }
    24. ?>