代码之家  ›  专栏  ›  技术社区  ›  Morteza Milani

重定向到Zend框架中的上一页

  •  28
  • Morteza Milani  · 技术社区  · 17 年前

    我想在登录页面中为我的登录表单操作(作为查询)添加一个重定向URL,以便登录后,可以访问他或她正在浏览的上一页。

    首先,我考虑使用Zend会话,并将每个页面的URL保存在一个变量中。但我在文档中看到它有开销。那么,有没有更好的方法呢?或者有没有其他方法可以使用Zend会话而不产生开销?

    11 回复  |  直到 13 年前
        1
  •  16
  •   Moshe Simantov    15 年前

    首先,您需要获取重定向的原始URL。 您可以通过Zend_Controller_请求类通过以下方式完成此操作:

    $url = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();
    

    或者简单地说:

    $url = $_SERVER['REQUEST_URI'];
    

    然后,棘手的部分是通过用户请求传递它。 我建议使用library zend_会话,尽管使用post参数也是合法的:

    $session = new Zend_Session_Namespace('Your-Namespace');
    $session->redirect = $_SERVER['REQUEST_URI'];
    

    请注意,我们保留的地址包括基路径。 若要重定向控制器类中的客户端,请禁用选项“prependbase”以丢失基路径插入:

    $this->_redirect($url, array('prependBase' => false));
    
        2
  •  8
  •   Jesta    17 年前

    我发现实现这一点的一个简单方法就是在您的登录表单中隐藏一个字段。

    现在,我不确定您的登录表单是通用HTML元素还是 Zend_Form 但是如果它是 森达型 ,您可以简单地添加以下内容:

    $this->addElement('hidden', 'return', array(
            'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),             
                ));
    

    然后在我的身份验证脚本中,像上面的注释一样,我有一个简单的重定向,它使用传入的值将它们返回到同一页。

    $this->_redirect($this->_request->getPost('return'));
    

    显然,在这两个示例中,它们只是为了压缩代码而编写的,可能并不代表实现代码的最佳方式。两种方法使用 getRequest() 在我的代码中实际上没有嵌入 redirect addElement 但是为了举例来说,我只是把它们放进去了。

    上面的答案显然也可以,除非你进行了大量的页面重定向。我现在用这种方式运行的主要原因是不是所有窗体都在运行 森达型 能够改变隐藏的 return 输入用于测试的文本框。

        3
  •  6
  •   gnarf    17 年前

    基本上和Jesta在他的答案中做的一样,但是我在我的“mw-form”类中添加了以下函数-这是我所有窗体的一个超类-很容易 $form->trackReferrer($this->getRequest()); 任何形式的控制器。getreferer()函数接受一个“default”参数(如果用户禁用了referer头,或者没有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_窗体创建:

    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
  •  3
  •   TomáÅ¡ Fejfar    17 年前

    我有一个预补丁插件用于授权。在它中,如果(并且仅当)用户需要被记录,我将请求URI保存到会话,在登录之后,我将重定向到会话。除了重定向到登录表单时,没有开销。但在这种情况下,开销是没有问题的。:)

    if(!$auth->hasIdentity()){
      $this->_insertLastUrlToSession();
      $this->redirect('/index/login');
    } else {
      //no overhead
    }
    
        5
  •  2
  •   Edward Hew    16 年前

    我知道这已经有了答案,但我也想把我的也扔进去,就像用一种不同的方法,用静态的方法剥皮猫的皮肤一样。

    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
  •  1
  •   Capitaine    14 年前

    这个Zend框架插件允许您保存当前和最后一个合格的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
  •  0
  •   Phliplip    15 年前

    除了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
  •  0
  •   Marcin Hubert    14 年前

    您可以尝试使用http_referer头,如下所示:

    // 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
  •  0
  •   chmurson    13 年前

    如果您不喜欢通过会话传递变量,您可以尝试以安全的方式获取$_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
  •  0
  •   Webdesign7 London    13 年前

    $this->_重定向($this->getRequest()->getServer('http_referer'));

        11
  •  -2
  •   Mark    17 年前

    我确信ZF中有一些内置的方法可以做到这一点,但我很懒惰,所以我是这样做的:

    创造你自己 应用程序控制器动作 类(create/library/app/controller/action.php)。从这个类中扩展所有控制器

    在每个控制器中,我调用$this->ou 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('/');
    
    推荐文章