【问题标题】:CakePHP 2.2.4: Redirect not Working When Using ComponentCakePHP 2.2.4:使用组件时重定向不起作用
【发布时间】:2013-01-26 21:15:52
【问题描述】:

我注意到重定向控制器方法有时无法正常工作。当我设置 debug > 0 时没有消息出现。我在调用重定向方法之前不回显任何代码,所以它不应该是因为“标头已发送”。

让我们看看我的 ArticlesController 添加操作,其中重定向在一个实例中起作用,但在另一个实例中不起作用。

public function add($page = null) {
    // Custom component to get if user has required access level
    // of page to write an article. If not, setflash to an error message
    // specific to user's access level and redirect.

    $access_message = $this->CustomPage->AccessMessage(4, $this->viewVars['access']);

    if($access_message){

        // Flash works but redirect does not
        $this->Session->setFlash(__($access_message));
        $this->redirect(array('action' => 'index', 'page' => $page));
        // Also tried
        // $this->redirect(array('controller'=>'articles', 'action' => 'index', 'page' => $page), null, true);
    } else
    {

    if ($this->request->is('post')) {

        $this->Article->create();
                if ($this->Article->save($this->request->data)) {

                    // BLAH BLAH save post, do other stuff
                    // BLAH BLAH save post, do other stuff

                    // This flash and redirect works
                    $this->Session->setFlash(__('The article has been saved'));
                    $this->redirect(array('action' => 'view', 'id' => $article_id, 'page' => $page));

                    } else {
                    $this->Session->setFlash(__('The article could not be saved. Please, try again.'));
                    } // end else if article cannot be saved
        } // if method is post
    } // end if user has access
} // end add action

它肯定与组件有关,但我不确定是什么。也许由于在使用组件后立即调用了重定向,因此“$this”试图在组件而不是控制器上执行重定向方法。我尝试了 $this->Article->redirect 并在重定向之前重新加载 Article 模型,但这些都不起作用。

我的组件代码是:

public function AccessMessage($required_level, $user_level) {

    if(!$user_level && $this->_View->viewVars['access']){
        $user_level = $this->_View->viewVars['access'];
    }

    if(!$required_level || !$user_level || $user_level != $required_level){
        $accessModel = ClassRegistry::init('Access');
        $access_message = $accessModel->field('access_message', array('Access.id' => $required_level));
     }

      return $access_message;
}

编辑 1: 好的,所以我进行了一些挖掘,以准确找出问题的根源。组件的使用不是我之前认为的问题。如果我的组件中只有

public function AccessMessage($required_level, $user_level) {

    if(!$user_level && $this->_View->viewVars['access']){
        $user_level = $this->_View->viewVars['access'];
    }

    if(!$required_level || !$user_level || $user_level != $required_level){
        $access_message = 1;
     }

      return $access_message;
}

然后就可以了。问题在于正确实现的这两行,因为它们返回了我期望的 $access_message 的值,但是它们干扰了重定向的能力。也许标头已经发出?

        $accessModel = ClassRegistry::init('Access');
        $access_message = $accessModel->field('access_message', array('Access.id' => $required_level));

请注意我也尝试过:

        $access_message = ClassRegistry::init('Access')->field('access_message', array('Access.id' => $required_level));

        $this->loadModel('Access');
        $access_message = $this->Access->field('access_message', array('Access.id' => $required_level));

要点:

组件要点:https://gist.github.com/970a951715205c222348

控制器要点:https://gist.github.com/2b90e5af2518a81672fb

访问模型要点:https://gist.github.com/bhndbrwneyes/f333a93f0a21302d832f

【问题讨论】:

  • 您是否在组件的_construct() 或任何回调(如initialize()startup() 等)中执行任何操作?
  • 这看起来太具体到您的代码 - 任何人都可以看到或重现“问题”?

标签: cakephp redirect controller


【解决方案1】:

您可能有空间before/after php Opening/Closing tags in controller and models。在打开标签之前从所有控制器和模型中删除所有结束标签以及任何空格。然后检查结果。

【讨论】:

  • 只是仔细检查了所有内容,不,我没有:(
  • 好的,我找到了,它实际上是我的 Access 模型的开始标记之前的一个空格。我在不同的模型上使用类注册表替换了我的组件代码,它运行良好,所以我知道问题必须在 Access 模型中。我一直在寻找结束标签周围的空格,但它在打开标签上。感谢您为我指明正确的方向。
  • 欢迎您,我也更新了答案,希望看到这个问题的人可以得到帮助。
【解决方案2】:

还没有答案,但至少你的代码中有一些变量可能没有定义,或者可能出现错误:

public function AccessMessage($required_level, $user_level) {

    if(!$user_level && $this->_View->viewVars['access']){
        $user_level = $this->_View->viewVars['access'];
    }

    if(!$required_level || !$user_level || $user_level != $required_level){
        $access_message = 1;
    }

    return $access_message;
}
  • 变量 $access_message 只有在不允许用户访问页面时才被定义
  • 如果根本没有设置 'access' viewVar 可能会发生错误

改成这样:

public function AccessMessage($required_level, $user_level) {
    $access_message = 0;

    if(!$user_level && $this->_View->get('access')){
        $user_level = $this->_View->get('access');
    }

    if(!$required_level || !$user_level || $user_level != $required_level){
        $access_message = 1;
    }

    return $access_message;
}

[更新] 看到你确实在你的要点上定义了 $access_message (https://gist.github.com/970a951715205c222348)

但是: 这将工作

App::uses('Component', 'Controller', 'ClassRegistry', 'Utility');

App::uses() 有两个参数;您想使用的“类”以及可以找到的位置。上面的行应该写成:

App::uses('Component',     'Controller/Component');
App::uses('Controller',    'Controller');
App::uses('ClassRegistry', 'Utility');

但不知ClassRegistry是否需要手动加载

[更新 2] 你的应用程序中确实发生了很多“奇怪”的事情,所以我想知道我们是否能够解决这个问题:

public function add($page = null) {
    $access = $this->viewVars['access'];

    if($this->CustomPage->AccessMessage(4, $access)){
        $this->Session->setFlash(__($this->CustomPage->AccessMessage(4, $access)));
        $this->redirect(array('action' => 'index', 'page' => $page));
    }

    // ......
}
  • 'viewVars['access']' 设置在哪里?
  • 您将 'viewVars['access']' 作为第二个参数 ($user_level) 传递给 AccessMessage(),但是 inside AccessMessage() 您试图再次使用相同的 viewVar如果未设置参数“$user_level”?
  • $this->CustomPage->AccessMessage() 被调用两次 以检查它是否返回任何内容,然后使用 它。效率不高

.

public function add($page = null) {
    // Where does is $this->viewVars['access'] come from? Where is it set?
    $access  = empty($this->viewVars['access'])? null : $this->viewVars['access'];
    $message = $this->CustomPage->AccessMessage(4, $access);

    if ($message) {
        $this->Session->setFlash(__($message));
        $this->redirect(array('action' => 'index', 'page' => $page));
    }

    // ......
}

进一步说明。 您仅在找到“消息”且不为空时才重定向用户,而不是基于当前用户的权限,您可以考虑将两者分开;

在您的组件中:

public function HasAccessLevel($required_level, $user_level) {
    if(!$user_level || $user_level != $required_level){
        return false;
    }

    return true;
}

public function AccessMessage($required_level) {
    return ClassRegistry::init('Access')->field('access_message', array('Access.id' => $required_level));
}

在您的控制器中:

public function add($page = null) {
    // Where does is $this->viewVars['access'] come from? Where is it set?
    $access  = empty($this->viewVars['access'])? null : $this->viewVars['access'];

    if($this->CustomPage->HasAccessLevel(4, $access)){
        $this->Session->setFlash(__($this->CustomPage->AccessMessage(4)));
        $this->redirect(array('action' => 'index', 'page' => $page));
    }

    // ......
}

【讨论】:

  • 好建议。投票,但是我的问题没有解决。我将 app:uses 更改为三个单独的行。 Access var 是在 AppController 中定义的,我也得到了组件中访问变量的检查,因为它已经被 ArticlesController 传递了。将 AccessMessage 函数拆分为 2 个单独的函数以提高效率,并按照说明在 ArticlesController 中使用,但仍然没有重定向。
【解决方案3】:

Cake 2:在组件顶部:添加

  public function initialize(Controller $controller) {
        $this->Controller = $controller;
    }

在函数内部你可以像这样重定向:

$this->Controller->redirect(array('plugin' => false, 'controller' => 'users', 'action' => 'index'));

【讨论】:

    【解决方案4】:

    如果调用了重定向,但您没有被重定向,我猜您在 index() 操作中进行了一些权限检查,以阻止访问。你能确认或发布整个控制器代码吗?

    【讨论】:

    • 我的 index() 中没有权限检查。 authAllow 允许在所有控制器中使用 index()。我的文章控制器中的 index() 仅显示 page_id = $page 的所有文章的列表。在 view() 中,我能够成功重定向到 index(),文章的 id 不存在。
    • 好的,那么究竟是什么意思 - “重定向不起作用”?您是否看到白屏,或者您是否仍在查看Articles/add?如果您删除CustomPage 组件并注释掉调用$access_message = $this->CustomPage->AccessMessage(4, $this->viewVars['access']);,重定向是否有效?如果是这样,我同意企鹅蛋,看起来你在组件或应用回调中有一些东西,beforeRedirect 也许?
    • 对你所说的一切都是肯定的。白屏仍在 add() 视图上。如果我注释掉组件的使用或者注释掉实际组件本身中的“return $access_message”,则可以工作。但我没有使用任何回调。
    • 所以实际上并不是组件本身的使用,而是$access_message的返回。
    • 好的,那么您的Access 模型有问题吗?发布此模型的代码也许是个好主意。或者只是确保您在 DB 表中有 accesses 或者您定义了 useTable 模型属性。在致电ClassRegistry::init() 之前,请尝试App::uses('Access', 'Model');。甚至可以检查它是否适用于调用$accessModel->findById($required_level, array('access_message'))...我真的很想知道你有什么问题;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 1970-01-01
    相关资源
    最近更新 更多