tra*_*nte 12 php redirect cakephp url-redirection cakephp-3.0
在我们的CakePHP 3应用程序中,我们发现了不同的行为.我们确信它在CakePHP 2中运行良好,所以我想在新版本中有些变化.
当用户访问此url:时/b2controller/myMethod,这些方法运行:  
AppController::beforeFilter()  
BController::beforeFilter()  
B2Controller::beforeFilter()  
B2Controller::myMethod()  
B2Controller::myMethod2()    
然后用户被重定向到此URL /ccontroller/myMethod10/   
但我们需要这个:
当用户访问 
 /b2controller/myMethod和$isOk条件true,然后重定向用户/ccontroller/myMethod10/,而不运行BController::beforeFilter(),B2Controller::beforeFilter(),B2Controller::myMethod()和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().
另请注意,还有其他类似的控制器CController使用beforeFilter重定向行为.
以下是3种有效的方法:
startupProcess在控制器中覆盖覆盖以下startupProcess方法AppController:
// In your AppController
public function startupProcess() {
    // Compute $isOk
    if ($isOk) {
        return $this->redirect('/c/myMethod10');
    }
    return parent::startupProcess();
}
这是一个简短而且非常干净的方法,所以如果可以,我会选择这个.如果这不符合您的需求,请参阅下文.
注意:如果使用此方法,则在计算时可能无法初始化组件,$isOk因为初始化完成后parent::startupProcess.
AppController:一种简单但不太干净的方式可能是从AppController::beforeFilter以下方式发送响应   :
public function beforeFilter(\Cake\Event\Event $event) {
    // Compute $isOk
    if ($isOk) {
        $this->response = $this->redirect('/c/myMethod10');
        $this->response->send();
        die();
    }
}
Dispatcher Filters使用更"干净"的方式Dispatcher Filters:
在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;
        }
    }
}
在config/bootstrap.php:
DispatcherFactory::add('Redirect');
你可以删除你的重定向AppController.如果你能够从中计算$isOk,这可能是最干净的方法DispatcherFilter.
请注意,如果您有beforeRedirect事件,则不会使用此方法触发这些事件.
编辑:这是我以前的答案,如果您有多个B类似的控制器,它将无法正常工作.
您需要返回返回的Response对象$this->redirect().实现此目的的一种方法是执行以下操作:
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
    }
}
if只有在没有重定向(parent::beforeFilter($event)没有返回Response对象)的情况下才执行代码.
注意:我不知道你如何计算isOk,但如果你在调用$this->redirect()时调用,请注意无限重定向循环/ccontroller/mymethod10.
| 归档时间: | 
 | 
| 查看次数: | 4169 次 | 
| 最近记录: |