Zend framework 重定向到zend framework中的上一页

Zend framework 重定向到zend framework中的上一页,zend-framework,url,session,redirect,Zend Framework,Url,Session,Redirect,我想在登录页面中为我的登录表单操作(作为查询)添加一个重定向URL,以便在登录后,可以访问他或她正在浏览的上一个页面 首先,我考虑使用Zend会话并将每个页面的url保存在一个变量中。但我在文档中看到它有开销。那么,有没有更好的办法呢?或者有没有其他方法可以在没有开销的情况下使用zend会话?我确信在ZF的某个地方有一些内置的方法可以做到这一点,但我很懒,所以我是这样做的: 创建自己的App\u Controller\u Action类(Create/library/App/Controller

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


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

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

创建自己的App\u Controller\u Action类(Create/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();
}
如果登录验证,则我将执行以下操作:

if (strlen($uri) > 0)
    $this->_redirect($uri);
else
    $this->_redirect('/');
$this->addElement('hidden', 'return', array(
        'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),             
            ));

我发现一个简单的方法就是在你的登录表单中有一个隐藏的字段

现在,我不确定您的登录表单是通用HTML元素还是实际上是
Zend_表单
的实例,但是如果它是
Zend_表单
的实例,您可以简单地添加以下内容:

if (strlen($uri) > 0)
    $this->_redirect($uri);
else
    $this->_redirect('/');
$this->addElement('hidden', 'return', array(
        'value' => Zend_Controller_Front::getInstance()->getRequest()->getRequestUri(),             
            ));
然后在我的身份验证脚本中,像上面的注释一样,我有一个简单的重定向,它使用传入的值将它们返回到同一页面

$this->_redirect($this->_request->getPost('return'));
显然,在这两个示例中,它们只是为了压缩代码而编写的,可能并不代表实现它的最佳方式。在我的代码中使用
getRequest()
的两个方法实际上并没有嵌入到
重定向
添加元素中,但出于示例目的,我只是将它们滑入其中


上面的答案显然也会起作用,除非你有一些大规模的页面重定向正在进行。我现在以这种方式运行我的表单的主要原因是,并不是所有表单都以
Zend_表单
运行,而且能够更改隐藏的
return
输入文本框的值以进行测试也很好

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


基本上与Jesta在回答中所做的相同,但我在我的“MW_Form”类中添加了以下函数——这是我所有表单的超类——非常容易
$Form->trackreferer($this->getRequest())从控制器以任何形式发送。getReferer()函数接受一个“default”参数(如果用户禁用了REFERER头,或者没有REFERER,您将需要一个默认位置重定向回该参数)

示例用法(来自控制器):


我知道这已经有了答案,但我也想把我的也加入进来,这是一种不同的交易方式,使用静态方法

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;
     }
}
这并不是一直运行,只是在需要的基础上运行


这就是全部代码,是我博客帖子的一部分()

除了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));

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

$url = Zend_Controller_Front::getInstance()->getRequest()->getRequestUri();
或者简单地说:

$url = $_SERVER['REQUEST_URI'];
然后,棘手的部分是通过用户请求传递它。 我建议使用库Zend_会话,尽管使用POST参数也是合法的:

$session = new Zend_Session_Namespace('Your-Namespace');
$session->redirect = $_SERVER['REQUEST_URI'];
请注意,我们保留的地址包括基本路径。 要重定向控制器类中的客户端,请禁用选项“prependBase”以丢失基路径插入:

$this->_redirect($url, array('prependBase' => false));

您可以尝试使用HTTP\U 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"));  

这个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>';
    }
}

如果您不喜欢通过会话传递变量,您可以尝试以安全的方式获取$\u SERVER['HTTP\u REFERER']变量。基本上,它会检查您的推荐人url和地址是否与您的服务器本地名称和方案(http/https)匹配

然后就


默认情况下,您可以设置本地uri('/')

$this->\u重定向($this->getRequest()->getServer('HTTP\u REFERER'))

显然,在应用程序上线之前,您需要清理$uri,我还没有这样做,一旦您知道所有可能接受的输入,谢谢您标记和Jesta,我更喜欢Jesta回答。因为我做了很多路由、转发、预分发等功能!!!无论如何,谢谢你。我等待更多答案。此解决方案的问题是数据丢失。场景:用户登录到应用程序并加载表单。他开始填表格。同时,会话过期,他需要再次登录。当他使用此解决方案提交表单时,他发布的数据将丢失。谢谢大家,所以,我将使用新的Zend_Session_命名空间,而不是_InsertLastUrlToSessionHelper中的Zend_Session::start(),哈?谢谢,谢谢。我读了你的博客文章和这个答案。您知道,在应用程序根本不使用会话的情况下使用表单时,这个问题的公认答案非常简单。但是web应用程序通常使用会话,因此添加另一个键/值对来存储以前的url是没有意义的,您的回答很有帮助。谢谢您的回复,非常感谢。谢谢你访问我的博客,我通常都有,没有访客:)。实际上我已经更新了那篇博客文章,但只是我的态度更包容其他用例,代码没有改变。祝您今天过得愉快!Gnarf看起来不错。但是“trackreferer”函数在哪个文件中运行?这是什么类型的课?它是一个助手还是什么?它在我的
my_Form
类中,它扩展了
Zend_Form
,我的所有表单都是从这个类扩展而来的……还可以序列化请求对象:
$session->redirect=serialize($this->getRequest())
。实际上,这就是我现在使用的解决方案,在o
$this->_redirect($url, array('prependBase' => false));
// 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"));  
<?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>';
    }
}
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('/');