ФорумПрограммированиеPHP для идиотовPHP и ООП → Исключения

Исключения

  • sap

    Сообщения: 2701 Репутация: N Группа: Кто попало

    Spritz 10 октября 2008 г. 13:13

    Начал вот вплотную использовать исключения. Да, стыдно, что так поздно :))) Есть вот пара вопросов.

    1. Допустим, самый банальный вариант:
    class db
    {
    // …

    public function sql_query($query)
    {
    $this->result = mysql_query($query)
    or $this->error(mysql_error().' in query '.$query);

    return $this->result;
    }

    private function error($message)
    {
    throw new dbException($message);
    }
    }


    Но, sql-запрос — это довольно часто нужная операция, и мне кажется логичней будет не каждый раз обрамлять код с запросом в try-catch, а сделать примерно так:

    // начало программы, подключение классов, конфигов и т. д.

    try {
    // а тут мы подключаем модули. конечно, они у меня не так подключаются, это для примера
    if (file_exists("includes/".$_GET['module']."/.inc.php"))
    include("includes/".$_GET['module']."/.inc.php")
    } catch (dbException $e) {
    // обрабатываем
    }

    То есть практически весь код загнать в один большой блок try-catch. Я правильно мыслю?
    Тогда второй вопрос.

    2. Зачем нужно наследовать от Exception, понятно — чтобы знать, какую именно ошибку отлавливаешь. Так? Какие еще есть выгоды от этого?

    3. Допустим, у меня есть кусок кода, который потенциально может породить два типа ошибок. Как их отлавливать?
    try {
    try {
    // этот ужасный кусок кода
    } catch (secondException $e2) {
    // обрабатываем
    }
    } catch (firstException $e1) {
    // обрабатываем
    }

    Так? Или есть более элегантный способ?)

    4. И последнее. Я сейчас использую свой шаблонизатор, основаный на нативных шаблонах. Выглядит это дело примерно так:
    $stemp = new STemp();

    // В index.tpl.php у нас основа, изменяюмую часть подключаем так:
    $stemp->assign("page", "news");

    $stemp->display("index.tpl.php");

    А в index.tpl.php:
    <html><head></head><body>
    <?php require_once($this->path.$this->page.".tpl.php") ?>
    </body></html>


    Было бы логично $stemp->display(); расположить в блоке try и отлавливать ошибку, если например, переменная $page не передана в шаблон. Но тогда в шаблоне придется писать:
    <html><head></head><body>
    <?php if(!file_exists($this->path.$this->page.".tpl.php")) throw new STempException('Fuck! Template not found.');
    require_once($this->path.$this->page.".tpl.php") ?>
    </body></html>

    А это, на мой взгяд, уже нарушение самой сути MVC. Какой, нафиг, file_exists в шаблоне? И тем более throw. Как тут быть?
  • kendo

    Сообщения: 446 Репутация: N Группа: Адекваты

    Spritz 10 октября 2008 г. 13:44, спустя 30 минут 42 секунды

    1. Да, загнать в один большой блок будет лучше
    2. А это дело удобства. Например, как в goDB исключения поделены на уровни: goDBException наследуется от Exception, а goDBConnectionError наследуется от goDBException, т.е. выстраиваем иерархию

    try {
    // какие-то действия, которые могут выбросить исключение
    } catch(goDBConnectionError $e){
    // обрабатываем событие, если возникла ошибка при подключении к БД
    } catch (goDBException $e) {
    // обрабатываем событие, если возникла ошибка в модуле goDB
    } catch (Exception $e) {
    // обрабатываем глобальное исключение
    }

    Вся сладость в том, что, например, мы можем опустить наследуемые исключения и обрабатывать всё совместно:

    try {
    // blah-blah-blah
    } catch (Exception $e) {
    // обрабатываем все исключения
    }

    3. А вот это, я считаю не есть хорошо, поскольку у нас ловятся исключения в двух местах. На мой взгляд, лучше делать несколько catch блоков для отлова разных исключений, как я показал в п.2
    4. а вот по этому поводу я, к сожалению, ничего сказать не могу, т.к. тут выводится ошибка, если файла не существует, а не выбрасывается исключение. Могу только порекомендовать почитать про собственные обработчики ошибок, но скорее всего они мало пригодятся :-) http://ru2.php.net/manual/ru/function.set-error-handler.php
  • sap

    Сообщения: 2701 Репутация: N Группа: Кто попало

    Spritz 10 октября 2008 г. 13:51, спустя 7 минут 16 секунд

    Спасибо.

    А с последним я сам уже придумал :) Можно устанавливать подключаемый файл отдельной функцией, и в ней проверять существование файла и выбрасывать исключение. Гибкость, конечно, пострадает, но фиг с ним.
  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 10 октября 2008 г. 14:16, спустя 25 минут 6 секунд

    у нас среди разработчиков есть шутка
    нахуя мы стока разных классов написали, стока шаблонов наделали, стока конфигов расконфигурили? проще все это объединить в один громадный класс и один огромный шаблон, а тестеры создадут один большой дефект!
    но недавно мы выяснили что трай-кетч может содержать только 4к строчек кода(((
  • kendo

    Сообщения: 446 Репутация: N Группа: Адекваты

    Spritz 10 октября 2008 г. 15:03, спустя 46 минут 43 секунды

    Мавр, я думаю, ты про это http://ru.wikipedia.org/wiki/Божественный_объект :-)
    Хм… А 4 тыс. кода включая вызовы йункций и методов или чистого кода? Если второе, то зачем делать весь код в блоке =)? Ведь можно как в Java вешать его только на те методы, которые выбрасывают исключение…
  • Trej Gun

    Сообщения: 5305 Репутация: N Группа: в ухо

    Spritz 10 октября 2008 г. 15:11, спустя 8 минут 5 секунд

    KENDO, я про джаву и говорю

Пожалуйста, авторизуйтесь, чтобы написать комментарий!