Przekierowanie do poprzedniej strony w zend framework
Chcę dodać adres URL przekierowania do mojej akcji formularzy logowania (jako zapytanie) na stronie logowania, więc po zalogowaniu można odwiedzić poprzednią stronę, na której surfował.
Najpierw pomyślałem o użyciu sesji Zend i zapisaniu adresu URL każdej strony w zmiennej. ale czytałem w dokumentacji, że ma nad głową. Czy jest na to lepszy sposób? a może jest inny sposób na wykorzystanie sesji zend bez zbędnych kosztów?
11 answers
Najpierw musisz pobrać oryginalny adres url przekierowania. Możesz to zrobić za pomocą klasy Zend_Controller_Request poprzez:
$url = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();
Lub po prostu przez:
$url = $_SERVER['REQUEST_URI'];
Następnie, najtrudniejszą częścią jest przepuszczenie go przez żądanie użytkownika. Zalecam Użycie biblioteki Zend_Session, pomimo użycia parametru POST jest również uzasadnione:
$session = new Zend_Session_Namespace('Your-Namespace');
$session->redirect = $_SERVER['REQUEST_URI'];
Zwróć uwagę, że adres, który przechowujemy, zawiera ścieżkę bazową. Aby przekierować klienta w klasie kontrolera, wyłącz opcję 'prependBase' na lose the base path insertion:
$this->_redirect($url, array('prependBase' => false));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-21 20:52:15
To, co znalazłem jako prostą metodę, aby to osiągnąć, to po prostu mieć ukryte pole w formularzu logowania.
Teraz nie jestem pewien, czy twój formularz logowania jest ogólnym elementem HTML, czy rzeczywiście jest instancją Zend_Form
, ale jeśli jest instancją Zend_Form
, możesz po prostu dodać:
$this->addElement('hidden', 'return', array(
'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),
));
Następnie w moim skrypcie uwierzytelniania, jak w komentarzu powyżej, mam proste przekierowanie, które wykorzystuje wartość przekazaną, aby przywrócić je do tej samej strony.
$this->_redirect($this->_request->getPost('return'));
Oczywiście w tych dwa przykłady, są one po prostu napisane, aby skompaktować kod i prawdopodobnie nie reprezentują najlepszego sposobu, aby go osiągnąć. Dwie metody wykorzystujące getRequest()
w moim kodzie w rzeczywistości nie są osadzone w redirect
lub addElement
, ale dla przykładu po prostu wsunąłem je tam.
Powyższa odpowiedź będzie oczywiście działać, jak również, chyba że masz jakieś ogromne przekierowanie strony dzieje. Głównym powodem, dla którego biegam teraz w ten sposób, jest to, że nie wszystkie moje formularze działają w Zend_Form
, a także miło jest móc zmienić wartość ukrytego pola tekstowego return
do celów testowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 17:58:58
Zasadniczo to samo, co robi Jeststa w swojej odpowiedzi, ale dodałem następujące funkcje do mojej klasy "MW_Form" - która jest superklasą wszystkich moich form-wystarczająco łatwo $form->trackReferrer($this->getRequest());
z kontrolera z dowolną formą. Funkcja getReferrer () pobiera argument "default" (który jeśli użytkownik ma wyłączone nagłówki REFERER lub nie ma referrer - będziesz chciał domyślnego miejsca do przekierowania z powrotem)
/**
* 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;
}
Dekorator używany-daje Ci dodatkową korzyść, że nie zużywasz żadnych wiersze w <dl>
utworzone przez 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;
}
}
Przykładowe użycie (z kontrolera):
$form = $description->getEditForm();
$form->trackReferrer($this->_request);
if ($this->_request->isPost())
{
if ($form->process($this->_request->getPost()))
{
return $this->_redirect($form->getReferrer('/page'));
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-09 01:20:04
Mam hak predispatch w wtyczce do autoryzacji. W nim jeśli (i tylko jeśli) użytkownik musi być zalogowany zapisuję URI żądania do sesji i po zalogowaniu Przekierowuję tam. Nie ma narzutu, chyba że przekierowanie do formularza logowania. Ale to sprawa, w której napowietrzność nie stanowi problemu. :)
if(!$auth->hasIdentity()){
$this->_insertLastUrlToSession();
$this->redirect('/index/login');
} else {
//no overhead
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 19:08:41
Widzę, że to już ma odpowiedź, ale ja też chciałbym dorzucić swoją, tak jak inny sposób obedrzeć kota, używając statycznych metod.
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;
}
}
To nie działa cały czas, tylko na podstawie potrzeby.
To cały kod, część mojego posta na blogu tutaj ( http://hewmc.blogspot.com/2010/08/simple-way-to-store-last-visited-url-in.html )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-02 14:18:16
Ta wtyczka Zend Framework pozwala zapisać aktualny i ostatni kwalifikowany adres url oraz odfiltrować niechciane adresy URL. zapraszam do korzystania i komentowania:
<?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>';
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-29 22:50:32
Oprócz gnarfs answer, zmodyfikowałem go tak, aby sprawdzał poprawność - dla tych z Was, którzy dostają kopa.
$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));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-06 11:08:20
Możesz spróbować użyć nagłówka HTTP_REFERRER w następujący sposób:
// 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"));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-08 11:09:54
Jeśli nie jesteś fanem przekazywania zmiennych przez sesję, możesz spróbować uzyskać zmienną $_SERVER['HTTP_REFERER'] w bezpieczny sposób. Zasadniczo sprawdza, czy adres URL odsyłającego pasuje do lokalnej nazwy serwera i schematu (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'];
}
}
A potem po prostu
$referrerUrl = My_Tools::safelyGetReferrerUrl('/');
Jako domyślne możesz ustawić lokalny uri ('/ ' )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-27 13:39:02
$this - > _redirect ($this->getRequest ()->getServer ('HTTP_REFERER'));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 10:12:12
Jestem pewien, że jest jakaś wbudowana metoda na zrobienie tego gdzieś w ZF, ale jestem leniwy, więc zrobiłem to w ten sposób:
Utwórz własną klasę App_Controller_Action (create /library/App/Controller/Action.php). Extend all of your controllers off of this class
W każdym z moich kontrolerów wywołuję $this - > _initauth (), funkcję wklejoną poniżej:
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();
}
W AuthController wykonuję następujące czynności, aby upewnić się, że mój formularz wskazuje na pełny adres 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'));
Jeśli login validates, następnie wykonuję następujące czynności:
if (strlen($uri) > 0)
$this->_redirect($uri);
else
$this->_redirect('/');
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 16:56:02