Cakephp 3重定向在父类的beforeFilter [英] Cakephp 3 redirect in beforeFilter of parent class

查看:776
本文介绍了Cakephp 3重定向在父类的beforeFilter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的CakePHP 3应用程序中,我们发现了一个不同的行为。

In our CakePHP 3 application we found a different behaviour. We're sure that it worked well in CakePHP 2, so I suppose something changed in new version.

当用户访问这个url: / b2controller时,我们确定它在CakePHP 2中运行良好。 / myMethod ,这些方法运行:

When user visits this url: /b2controller/myMethod, these methods run:

AppController::beforeFilter()  
BController::beforeFilter()  
B2Controller::beforeFilter()  
B2Controller::myMethod()  
B2Controller::myMethod2()    

那么用户将被重定向到此网址 / ccontroller / myMethod10 /

then user is redirected to this url /ccontroller/myMethod10/

但我们需要这样:

当用户访问
/ b2controller / myMethod $ isOk 条件是 true ,然后将用户重定向到 / ccontroller / myMethod10 / ,而不运行 BController :: beforeFilter() B2Controller :: beforeFilter() B2Controller :: myMethod() BController :: MyMethod2()

When user visits /b2controller/myMethod and $isOk condition is true, then redirect user to /ccontroller/myMethod10/, without running BController::beforeFilter(), B2Controller::beforeFilter(), B2Controller::myMethod() and BController::MyMethod2().

我们的最小代码如下:

class AppController {
  function beforeFilter(Event $event) {
        // set $isOk variable
        if ($isOk == TRUE) {
           return $this->redirect('/ccontroller/myMethod10/');
        }
        $aa=1;
        $ab=2;
  }
}

class BController extends AppController {
  function beforeFilter(Event $event) {
    parent::beforeFilter($event);

    $a=1;
    $b=2;
  }

  function myOtherMethod() {
      myOtherMethod2();
  }

  function myOtherMethod2() {
      ...
      ...
  }
}

class B2Controller extends BController {
  function beforeFilter(Event $event) {
    parent::beforeFilter($event);

    $m1=1;
    $m2=2;
  }

  function myMethod() {
      myMethod2();
  }

  function myMethod2() {
      ...
      ...
  }
}

class CController extends AppController {
  function beforeFilter(Event $event) {
    parent::beforeFilter($event);
  }

  function myMethod10() {
      ...
      ...
      ...
  }
}

如何让用户从主类的beforeFilter重定向到另一个控制器动作?请注意,重定向发生。但是在调用 myMethod() myMethod2()后重定向用户。

How can I make user to redirect to another controller action, from the beforeFilter of main class ? Note that redirect occurs. But user is redirected after calling myMethod() and myMethod2().

还要注意,还有其他控制器如 CController 使用beforeFilter重定向行为。

Also note that there is other controllers like CController that uses beforeFilter redirect behaviour.

推荐答案

以下是3种方法:

覆盖 AppController的 startupProcess 方法

Override the startupProcess method of AppController:

// In your AppController
public function startupProcess() {
    // Compute $isOk
    if ($isOk) {
        return $this->redirect('/c/myMethod10') ;
    }
    return parent::startupProcess () ;
}

这是一个简短而漂亮的方法,所以我会去这个如果可能的话。如果这不符合您的需要,请参阅下面的两个方法。

This is a short and pretty clean method, so I would go for this one if possible. If this does not match your need, see the two methods below.

注意:如果使用此方法, code> $ isOk ,因为初始化由 parent :: startupProcess 完成。

Note: If you use this method, your components may not be initialized when you compute $isOk since the initialize is done by parent::startupProcess.

一个容易,但不是真的干净方式可以是在 AppController 中发送响应:

One easy but not really clean way may be to send the response in your AppController:

public function beforeFilter (\Cake\Event\Event $event) {
    // Compute $isOk
    if ($isOk) {
        $this->response = $this->redirect('/c/myMethod10') ;
        $this->response->send () ;
        die () ;
    }
}


$ b < //book.cakephp.org/3.0/en/development/dispatch-filters.htmlrel =nofollow> 调度过滤器

一个更干净的方式是使用

Method 3 - Use Dispatcher Filters

A more "clean" way would be to use Dispatcher Filters:

php ::

In src/Routing/Filter/RedirectFilter.php:

<?php

namespace App\Routing\Filter;

use Cake\Event\Event;
use Cake\Routing\DispatcherFilter;

class RedirectFilter extends DispatcherFilter {

    public function beforeDispatch(Event $event) {
        // Compute $isOk
        if ($isOk) {
            $response = $event->data['response'] ;
            // The code bellow mainly comes from the source of Controller.php
            $response->statusCode (302) ;
            $response->location (\Cake\Routing\Router::url('/c/myMethod10', true));
            return $response ;
        }
    }
}

bootstrap.php :

In config/bootstrap.php:

DispatcherFactory::add('Redirect');

您可以删除 AppController 。如果您能够从调度过滤器中计算 $ isOk ,这可能是最干净的方式。

And you can remove the redirection in your AppController. This may be the cleanest way if you are able to compute $isOk from the Dispatcher Filter.

请注意,如果您有 beforeRedirect 事件,则不会使用此方法触发。

Note that if you have beforeRedirect event, these won't be triggered with this method.

编辑:这是我以前的答案,如果你有多个 code> -like controllers。

This was my previous answer which does not work very well if you have multiple B-like controllers.

正如我在评论中说的,您需要返回 Response $ this-> redirect()返回的对象。实现这一点的一种方法是通过执行以下操作(我不知道是否有更好的/更清洁的方法来做到这一点):

As I was saying in the comments, you need to return the Response object returned by $this->redirect (). One way of achieving this is by doing the following (I don't know if there is a better/cleaner way to do this):

class BController extends AppController {

    public function beforeFilter (\Cake\Event\Event $event) {
        $result = parent::beforeFilter ($event) ;
        if ($result instanceof \Cake\Network\Response) {
            return $result ;
        } 
        // Your stuff
    }

}


b $ b

这对于我来说,如果如果没有重定向( parent :: beforeFilter($事件)未返回响应对象。

我不知道如何设置 isOk ,但是如果调用 $ this-> redirect() )时调用 / ccontroller / mymethod10

Note: I don't know how you set isOk, but be careful of infinite redirection loop if you call $this->redirect () when calling /ccontroller/mymethod10.

这篇关于Cakephp 3重定向在父类的beforeFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆