Cakephp 3重定向在父类的beforeFilter [英] Cakephp 3 redirect in beforeFilter of parent class
问题描述
在我们的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屋!