Ответ 1
Спустя почти год работы над хардкорным проектом, который использует Phalcon за пределами его возможностей, я хотел прояснить несколько вещей и ответить на мой собственный вопрос. Чтобы понять, как правильно выполнять переадресацию и переадресацию, вам нужно немного понять, как работает метод Dispatcher:: dispatch.
Взгляните на код здесь, хотя все это C mumbo-jumbo для большинства из нас, его действительно хорошо написано и задокументировано. В двух словах это то, что он делает:
- Диспетчер вводит цикл while до тех пор, пока свойство
_finished
не станетtrue
или оно обнаруживает рекурсию. - Внутри цикла он немедленно устанавливает это свойство в
true
, поэтому, когда он запускает следующую итерацию, он автоматически будет break. - Затем он получает информацию о контроллере/действии, которые изначально поставляются маршрутизатором в приложении, и выполняет различные проверки. До и после этого он также дополняет множество событий, связанных с бизнесом.
- Наконец, вызывает метод действия в контроллере и updates the
_returnedValue
с (угадайте, что!) возвращаемое значение. - Если во время вызова действия вы вызываете метод
Dispatcher::forward
, он будет обновить свойство_finished
доfalse
, что будет разрешите цикл while продолжить с шага 2 этого списка.
Итак, после перенаправления или пересылки вам необходимо убедиться, что код не выполняется только, если это часть ожидаемой логики. Другими словами, вам не нужно возвращать результат return $this->response->redirect
или return $this->dispatcher->forward
.
Выполнение последнего может показаться удобным, но не очень правильным и может привести к проблемам. В 99,9% случаев ваш контроллер ничего не должен возвращать. Исключение будет, когда вы действительно знаете, что делаете, и хотите изменить поведение процесса рендеринга в вашем приложении, возвратив объект ответа. Кроме того, ваша IDE может жаловаться на несогласованные операторы return.
Чтобы завершить, правильный способ перенаправления из контроллера:
// Calling redirect only sets the 30X response status. You also should
// disable the view to prevent the unnecessary rendering.
$this->response->redirect('/profile');
$this->view->disable();
// If you are in the middle of something, you probably don't want
// the rest of the code running.
return;
И переслать:
$this->dispatcher->forward(['action' => 'profile']);
// Again, exit if you don't need the rest of the logic.
return;