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?

Author: jason, 2009-08-08

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));
 16
Author: Moshe Simantov,
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.

 8
Author: Jesta,
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'));
  }
}
 6
Author: gnarf,
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
}
 3
Author: Tomáš Fejfar,
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 )

 2
Author: Edward Hew,
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>';
    }
}
 1
Author: Capitaine,
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));
 0
Author: Phliplip,
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"));  
 0
Author: Marcin Hubert,
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 ('/ ' )

 0
Author: chmurson,
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'));

 0
Author: Webdesign7 London,
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('/');
 -2
Author: Mark,
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