обработка редиректов как исключений

Sam

Новичок
обработка редиректов как исключений

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

соответственно может попробовать

PHP:
try {
    //bla-bla..
    
    throw redirectException('http://where-to-redirect')

    //bla-bla..
} catch redirectException($re) {
    $some_main_object->exit();
    $some_main_object->redirect($re->getMessage());
}
при этом $some_main_object может быть observable и сообщать своим observeram типа всё, закругляемся.

хотелось бы услшать ваше мнение об этом всём. пробовал ли кто-то?
 

moxnatiy

Новичок
не очень понятно для чего здесь использовать механизм исключений?

чем не нравиться такой вариант

PHP:
//bla-bla...
if ( chto_to_proizoshlo ) {
     $some_main_object->exit(); 
     $some_main_object->redirect('http://where-to-redirect');
}
 

Sam

Новичок
потому что таких редиректов может быть много


PHP:
//bla-bla...
if ( chto_to_proizoshlo ) {
     $some_main_object->exit(); 
     $some_main_object->redirect('http://where-to-redirect-1');
}


//bla-bla...

$some_main_object->exit(); 
$some_main_object->redirect('http://where-to-redirect-2');


//bla-bla...

$some_main_object->exit(); 
$some_main_object->redirect('http://where-to-redirect-3');

//bla-bla...
 

whirlwind

TDD infected, paranoid
Sam а если адрес редиректа поменяется? Лопатить весь код? Кроме того, это никакого отношения к исключениям не имеет. Это пример неправильного использования исключений. Исключение нужно обрабатывать - иначе проге кирдык. И в коде не должно быть данных.
 

Sam

Новичок
whirlwind
что значит "никакого отношения не имеет"? потребность редиректнуть юзера - самая что ни на есть исключительная ситуация, обработку которой мы переносим в одно место.

а насчёт адреса редиректа - как раз не надо весь код лопатить. не понял твою мысль
 

whirlwind

TDD infected, paranoid
исключительная ситуация != исключение

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

-~{}~ 11.01.06 14:12:

>как раз не надо весь код лопатить
как это не надо? у Вас адрес редиректа указан при генерации исключения. Или генерация исключения по Вашему не является частью кода?
 

Sam

Новичок
ок, типовая так типовая.
но что мне мешает подойти к обработке редиректов именно так кроме абстрактного утверждения "обработка редиректов никакого отношения к исключениям не имеет"?

куда требуется перенаправить ингда мы узнаем именно перед самим редиректом, а следовательно в момент генерации исключения. это не всегда что-то типа /login/ или /error/.
например когда мы освобождаем $_POST.
 

whirlwind

TDD infected, paranoid
>но что мне мешает
Ничего не мешает. И даже на первый взгляд вроде никаких сложностей не видно. Но вот беда, грабли всегда выявляются когда написана куча кода и для исправления придется всю эту кучу модифицировать. По этому прежде чем использовать какое то нестандартное решение следует подумать не семь раз, а сорок девять.

-~{}~ 11.01.06 14:55:

>куда требуется перенаправить ингда мы узнаем именно перед самим редиректом, а следовательно в момент генерации исключения

Это вовсе не подтверждает необходимость указания адреса в коде. Вообще программирование - это манипулирование абстракциями. Используйте псевдоданные

'INVALID_PASS' => 'http://sss',
'INVALID_LOGIN' => 'http://eee'

вынесите это в массив и храните где нибудь в конфиге. Но это уже не тема исключений.
 

Sam

Новичок
По этому прежде чем использовать какое то нестандартное решение следует подумать не семь раз, а сорок девять.
согласен. вот я и думаю )

по поводу модифицируемости - к исключениям это действительно не относится, как вы сказали но в порядке флейма:

в том-то и дело что адрес зачастую формируется, их могут быть сотни различных. константы пойдёт только для стандартных вроде login или error. тогда просто



PHP:
try {
    //bla-bla..
    // надо скинуть на логин
    throw redirectException(LOGIN_ADDR)

    //bla-bla..
} catch redirectException($re) {
    $some_main_object->exit();
    $some_main_object->redirect($re->getMessage());
}
 

whirlwind

TDD infected, paranoid
>не очень здорово когда приложение заканчивает работу где ему вздумается - часто приходится перед выходом что-то делать (писать в базу какие-то изменения, логировать что-то и тд)

Вот где у Вас ключевой момент? Используете exit? Избавьтесь от него! Добейтесь того, что бы все Ваши функции/методы завершали свою работу естественным образом.
 

Sam

Новичок
пока использую exit. стало стыдно вот и придумываю что-то поправильнее. )

просто без exit() пока получается что много лишней работы делаем. а исключения эту проблему решают.
 

whirlwind

TDD infected, paranoid
Исключение в этом случае - это усугубление exit-а. Количество проблем увеличится пропорционально

>не семь раз, а сорок девять.

-~{}~ 11.01.06 15:20:

PS.
>просто без exit() пока получается что много лишней работы делаем

Вам пора переходить на ООП, если еще не перешли. А если перешли, то рефакторинг: делите сложное на простое и инкапсулируйте.
 

Sam

Новичок
>Количество проблем увеличится пропорционально
так а в чём проблемы в данном случае?

на ооп считаю что перешёл ))
 

whirlwind

TDD infected, paranoid
>так а в чём проблемы в данном случае

Давайте не будем переливать из пустого в порожнее. Вам не нравится нынешний дизайн кода? Неудобно модифицировать и сопровождать собственные продукты? Используйте опыт других признанных программистов - купите книжку по рефакторингу. На рассмотрение всех частных случаев уйдет масса времени, которого у нас всех не хватает. Могу только посоветовать - не использовать исключения таким образом. Принимать или не принимать мой совет - дело Ваше.
 

.des.

Поставил пиво кому надо ;-)
Sam в приведенном примере, действительно, не очень заметны все минусы использования исключений таким образом.
И дело даже не в передаче данных, дело в том что есть неписанное правило - не использовать исключения для контролирования порядка исполнения программы. Использование исключений для flow control приводит к тем же проблемам, что и в случае использование инструкции goto.

Но если это действительно улучшает читабельность вашего кода, и вы идете на это сознавая все возможные проблемы %), то тут как и в случае преднамеренной денормализации бд иногда может быть оправдано.
 
Сверху