Перенаправление на предыдущую страницу в zend framework
Я хочу добавить URL-адрес перенаправления к моему действию форм входа (как запрос) на странице входа, поэтому после входа в систему можно посетить предыдущую страницу, которую он или она занимался серфингом.
Сначала я подумал об использовании Zend Session и сохранил URL-адрес каждой страницы в переменной. но я прочитал в документации, что у него есть накладные расходы. Итак, есть ли лучший способ сделать это? или есть другой способ использовать zend-сессию без накладных расходов?
Ответы
Ответ 1
Во-первых, вам нужно взять исходный url для перенаправления.
Вы можете сделать это с помощью класса Zend_Controller_Request с помощью:
$url = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();
или просто:
$url = $_SERVER['REQUEST_URI'];
Тогда сложная часть - передать ее через запрос пользователя.
Я рекомендую использовать библиотеку Zend_Session, несмотря на то, что использование параметра POST также является законным:
$session = new Zend_Session_Namespace('Your-Namespace');
$session->redirect = $_SERVER['REQUEST_URI'];
Обратите внимание, что адрес, который мы сохранили, содержит базовый путь.
Чтобы перенаправить клиента в класс контроллера, отключите опцию "prependBase", чтобы потерять вставку базового пути:
$this->_redirect($url, array('prependBase' => false));
Ответ 2
То, что я нашел в качестве простого метода для этого, - это просто скрытое поле в вашей форме входа.
Теперь, не уверен, что ваша форма входа является общим элементом HTML или на самом деле является экземпляром Zend_Form
, но если это экземпляр Zend_Form
, вы можете просто добавить следующее:
$this->addElement('hidden', 'return', array(
'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),
));
Затем в моей аутентификации script, как и в предыдущем комментарии, у меня есть простая переадресация, которая использует значение, переданное в, чтобы вернуть их на ту же страницу.
$this->_redirect($this->_request->getPost('return'));
Очевидно, что в этих двух примерах они просто записываются для уплотнения кода и, вероятно, не представляют собой лучший способ его выполнения. Два метода, использующих getRequest()
в моем коде, фактически не встроены в redirect
или addElement
, но, например, цели, я просто их скользил.
Ответ выше, очевидно, будет работать, если у вас нет массового перенаправления страниц. Основная причина, по которой я сейчас использую этот способ, заключается в том, что не все мои формы работают в Zend_Form
, а также хорошо могут изменять значение скрытого текстового поля ввода return
для целей тестирования.
Ответ 3
В основном то же самое, что Джеста делает в своем ответе, но я добавил следующие функции в мой класс "MW_Form" - суперкласс всех моих форм - достаточно легкий, чтобы $form->trackReferrer($this->getRequest());
от контроллера с любой формой. Функция getReferrer() принимает аргумент "по умолчанию" (который, если у пользователя отключены заголовки REFERER, или нет реферера, - вы хотите, чтобы место по умолчанию было перенаправлено обратно)
/**
* Adds a form element named "referrer" and sets its default value to either
* the 'referrer' param from the request, or the HTTP_REFERER header.
*
* @param Zend_Controller_Request_Abstract $request
* @return MW_Form
* @author Corey Frang
*/
public function trackReferrer(Zend_Controller_Request_Abstract $request)
{
$this->addElement('hidden', 'referrer');
$this->setDefault('referrer',
$request->getParam('referrer',
$request->getServer('HTTP_REFERER')));
// HTTP_REFERER not HTTP_REFERRER - grrr HTTP spec misspellings
// use no decorator for the actual form element
$this->referrer->setDecorators(array());
// use our custom "referrer" decorator to stick the hidden before the <dl>
$decorators = $this->getDecorators();
$this->clearDecorators();
foreach ($decorators as $class=>$decorator)
{
if (substr($class,-5) == '_Form') {
$this->addDecorator('Referrer');
$added = true;
}
$this->addDecorator($decorator);
}
if (!$added) $this->addDecorator('Referrer');
return $this;
}
/**
* Returns the referrer field if it exists.
*
* @return string | false
* @param mixed $default The value to return if referrer isn't set
* @author Corey Frang
**/
public function getReferrer($default = false)
{
if (!isset($this->referrer)) return $default;
$val = $this->referrer->getValue();
if ($val) return $val;
return $default;
}
Используемый декоратор - дает вам дополнительное преимущество в том, что вы не используете ни одного ряда в <dl>
, созданных zend_form:
class MW_Form_Decorator_Referrer extends Zend_Form_Decorator_Abstract {
/**
* Attaches the standard "ViewHelper" decorator for the 'referrer' element
* prepended on the content
*
* @return void
* @author Corey Frang
**/
public function render($content)
{
$form = $this->getElement();
if ($form instanceOf MW_Form)
{
$referrer = $form->referrer;
if ($referrer)
{
$decorator = new Zend_Form_Decorator_ViewHelper(array('placement'=>self::PREPEND));
$decorator->setElement($referrer);
return $decorator->render($content);
}
}
return "Error - No Referrer Found".$content;
}
}
Пример использования (с контроллера):
$form = $description->getEditForm();
$form->trackReferrer($this->_request);
if ($this->_request->isPost())
{
if ($form->process($this->_request->getPost()))
{
return $this->_redirect($form->getReferrer('/page'));
}
}
Ответ 4
У меня есть предварительный переход в плагин для авторизации. В нем, если (и только если) пользователь должен быть зарегистрирован, я сохраняю URI запроса на сеанс и после входа в него я перенаправляю туда. Накладных расходов нет, кроме как при переходе на форму входа. Но это случай, когда накладные расходы не являются проблемой.:)
if(!$auth->hasIdentity()){
$this->_insertLastUrlToSession();
$this->redirect('/index/login');
} else {
//no overhead
}
Ответ 5
Я вижу, что у этого уже есть ответ, но я тоже хотел бы использовать мой ключ, так же, как другой способ скрыть вид кошки, используя статические методы.
class App_Helpers_LastVisited {
/**
* Example use:
* App_Helpers_LastVisited::saveThis($this->_request->getRequestUri());
*/
public static function saveThis($url) {
$lastPg = new Zend_Session_Namespace('history');
$lastPg->last = $url;
//echo $lastPg->last;// results in /controller/action/param/foo
}
/**
* I typically use redirect:
* $this->_redirect(App_Helpers_LastVisited::getLastVisited());
*/
public static function getLastVisited() {
$lastPg = new Zend_Session_Namespace('history');
if(!empty($lastPg->last)) {
$path = $lastPg->last;
$lastPg->unsetAll();
return $path;
}
return ''; // Go back to index/index by default;
}
}
Это не работает постоянно, только при необходимости.
Что весь код, часть моего сообщения в блоге здесь (http://hewmc.blogspot.com/2010/08/simple-way-to-store-last-visited-url-in.html)
Ответ 6
Этот плагин Zend framework позволяет вам сохранять текущий и последний квалифицированный URL-адрес и отфильтровывать нежелательные URL-адреса. не стесняйтесь использовать и комментировать:
<?php
class Plugins_PageLog extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request){
$module = $request->getModuleName();
$controller = $request->getControllerName();
$action = $request->getActionName();
$params=$request->getParams();
// to grap urls that are in default module, not in auth controller, and not an error url
$controller2= Zend_Controller_Front::getInstance();
if ($controller2->getDispatcher()->isDispatchable($request)
&& ( $module == 'default' || $module == NULL )
&& $controller != 'auth'
&& ( !isset($params['error_handler']))
) {
// init 2 session variables: the current and last qualified url
if (!isset($_SESSION['redirect'])) $_SESSION['redirect'] = '';
if (!isset($_SESSION['last_visited_url'])) $_SESSION['last_visited_url'] = '';
// tempurl is to save current qualified url temporarily to ensure current and last qualified url will not be same
if (!isset($tempUrl)) $tempUrl = '';
if ($_SESSION['last_visited_url'] != $_SESSION['redirect']) {
$tempUrl = $_SESSION['redirect'];
$tempParams = $_SESSION['redirect_params'];
}
// save current qualified url
$_SESSION['redirect']=$request->getRequestUri();
$_SESSION['redirect_params'] = $params;
// to ensure there are no duplicated urls due to browser refresh
if ($tempUrl != $_SESSION['redirect']){
$_SESSION['last_visited_url'] = $tempUrl;
$_SESSION['last_visited_url_params'] = $tempParams;
}
}
//echo '<pre>';var_dump($_SESSION['last_visited_url']);echo '</pre>';
//echo '<pre>';var_dump($_SESSION['redirect']);echo '</pre>';
}
}
Ответ 7
В дополнение к ответу gnarfs я модифицировал его, чтобы он подтвердил - для тех из вас, кто его ударил.
$this->addDecorator(array('WrapClose' => 'HtmlTag'), array('tag' => 'div', 'placement' => 'PREPEND', 'closeOnly' => true));
$this->addDecorator('Referrer');
$this->addDecorator(array('WrapOpen' => 'HtmlTag'), array('tag' => 'div', 'placement' => 'PREPEND', 'openOnly' => true));
Ответ 8
Вы можете попробовать использовать заголовок HTTP_REFERRER следующим образом:
// str_replace is the easiest way to get rid of domain - u can also preg_replace it
return str_replace("http://".Zend_Controller_Front::getInstance()->getRequest()->getServer("HTTP_HOST"),"",Zend_Controller_Front::getInstance()->getRequest()->getServer("HTTP_REFERER"));
Ответ 9
Если вы не являетесь поклонником передачи переменных через сеанс, вы можете попытаться получить переменную $_SERVER ['HTTP_REFERER'] безопасным способом. В основном он проверяет, соответствует ли ваш URL-адрес реферера и соответствует ли вашему локальному имени вашего сервера и схеме (http/https).
class My_Tools
{
public static function doesUrlMatchServerHttpHost($url)
{
$scheme = Zend_Controller_Front::getInstance()->getRequest()->getScheme();
$httpHost = Zend_Controller_Front::getInstance()->getRequest()->getHttpHost();
$needleUrl = $scheme.'://'.$httpHost.'/';
if (strpos($url, $needleUrl) !== 0)
{
return false;
}
return true;
}
public static function safelyGetReferrerUrl($default)
{
if ( isset($_SERVER['HTTP_REFERER']) == false){
return $default;
}
if (self::doesUrlMatchServerHttpHost($_SERVER['HTTP_REFERER']) == false){
return $default;
}
return $_SERVER['HTTP_REFERER'];
}
}
А потом просто
$referrerUrl = My_Tools::safelyGetReferrerUrl('/');
По умолчанию вы можете установить локальный uri ('/')
Ответ 10
$это → _ редирект ($ this- > GetRequest() → getServer ( 'HTTP_REFERER'));
Ответ 11
Я уверен, что есть какой-то встроенный метод для этого где-то в ZF, но я ленив, поэтому я сделал это следующим образом:
Создайте свой собственный класс App_Controller_Action (создайте/library/App/Controller/Action.php). Расширьте все ваши контроллеры из этого класса
В каждом из моих контроллеров я вызываю $this → _ initAuth(), как показано ниже:
protected function _initAuth()
{
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity() && strcmp($_SERVER['REQUEST_URI'], '/auth/login') <> 0)
$this->_redirect('/auth/login' . $_SERVER['REQUEST_URI']);
else
$this->_identity = $auth->getIdentity();
}
В моем AuthController я делаю следующее, чтобы убедиться, что моя форма указывает на полный URL:
$uri = str_replace('/auth/login','',$_SERVER['REQUEST_URI']);
if (strlen($uri) > 0)
$form->setAction($this->_helper->url('login') . $uri);
else
$form->setAction($this->_helper->url('login'));
Если логин проверяется, я делаю следующее:
if (strlen($uri) > 0)
$this->_redirect($uri);
else
$this->_redirect('/');