2013-10-07 211 views
1

在用户授权失败后,我想将他们转发回登录页面。目前,_forward方法会导致Zend挂起并给出超时错误(超出30秒)。Zend _forward在身份验证失败后失败(Zend Framework 1)

登录页面的代码同时处理一个登录和注册表格,并转发到授权控制:

public function indexAction() { 

    if ($this->_request->isPost()) { 
     $formData = $this->_request->getPost(); 

     if (array_key_exists('signUp', $formData)) { 
      $authAction = 'signup'; 
      $form = 'signupForm'; 
     } elseif (array_key_exists('logIn', $formData)) { 
      $authAction = 'login'; 
      $form = 'loginForm'; 
     } 

     if ($this->$form->isValid($formData)) { 
      $this->_forward($authAction, 'user-auth', null, $formData); 
     } else { 
      $this->$form->populate($formData); 
     } 
    } 
} 

这工作得很好,并重定向到身份验证控制器成功。认证控制器的登录操作中的代码是这样的:

public function loginAction() { 
    $formData = $this->_request->getPost(); 

    $authAdapter = new My_Auth_Adapter(); 
    $authAdapter->setTableName('user') 
       ->setIdentity($formData['username']) 
       ->setCredential($formData['password']) 
       ->setIdentityColumn('username') 
       ->setCredentialColumn('password'); 
    $result = $authAdapter->authenticate(); 

    if ($result->isValid()) { 
     // success, all good 
    } else { 
     $this->_forward('index', 'login', 'default', $formData); 
    } 
} 

我们到达这里很好,并且成功的授权按预期工作。然而,在我的else语句中,将另一个转发回原始登录控制器(我希望填充用户名以及发回错误消息)会导致程序挂起,尽管重定向工作正常。

我认为这可能是因为登录控制器重新检测发布数据,并且我陷入了无限循环,但是删除$ formData作为最后一个参数并不会改变任何内容。

我也试过$ formData ['errMsg'] ='任何'上方的转发,然后检查密钥是否存在,或者如果它设置在登录控制器,但这并不会改变一件事情。

有趣的是,我收到引用验证DBTABLE适配器超时错误:

Fatal error: Maximum execution time of 30 seconds exceeded in /Applications/MAMP/MampServer/mysite/library/Zend/Auth/Adapter/DbTable.php on line 174 

任何想法,以什么可能会发生?

回答

1

我认为你是无限循环loginAction()indexAction()之间。

查看拨打电话forward()redirect()动作帮手之间的区别。前者,forward()内部将更改$request->isDispatched() == false - 这意味着前端控制器将执行目标控制器操作而不是新的HTTP请求。

这样做的结果是$this->_request->isPost()将始终为true,因此$this->$form->isValid($formData)也将是真实的,这意味着您在圈子中回顾。

我知道下面的方法与您的方法非常不同,但我相信这是Zend 1控制器关注点的传统分离。

// ... SomeController.php 

    public function getLoginForm(); 

    public function getSignupForm(); 

    protected function authenticate($username, $password) 
    { 
    $authAdapter = new My_Auth_Adapter(); 
    $authAdapter->setTableName('user') 
       ->setIdentity($username) 
       ->setCredential($password) 
       ->setIdentityColumn('username') 
       ->setCredentialColumn('password'); 
    $result = $authAdapter->authenticate(); 

    return ($result->isValid()) ? true : false; 
    } 

    public function indexAction() 
    { 
    $form = $this->getLoginForm(); 
    $request = $this->getRequest(); 

    if ($request->isPost()) { 
     if ($form->isValid($request->getPost())) { 

     if ($this->authenticate($form->getValue('username'), $form->getValue('username'))) { 
      $this->redirect('/members'); // Successfully logged in 
     } 
     } 
    } 
    $this->view->form = $form; 
    } 

    public function signupAction() 
    { 
    // stuff only for signups! 
    } 

编辑为了详细说明:forward()是控制器动作助手。它的工作仅仅是修改Zend_Controller_Request_Http实例。 Zend_Controller_Request_Http类是在控制器中调用$this->getRequest()时返回的类。

Request实例将所有对$_POST$_GET的访问进行封装,然后将其存储为对象内的值。呼叫如$request->setParam('someparam', 123)设置或获取这些值,而不是标准的直接访问$_POST['someparam']$_GET['someparam']

特殊情况的值为module,controller,actiondispatched。这些是Zend_Controller_Front调度员使用的密钥,当试图确定正确的控制器到实例化和动作方法到执行

如何dispatch loop作品的简单的例子:

while(! $request->isDispatched()) { 

    $request->setDispatched(true); 

    // If at any point here we change setDispatched(true) 
    // perhaps in a controller action with a call to forward() 
    // then the whole dispatch loop will be called again 
    // perhaps creating a different controller 

    $controllerName = $request->getControllerName(); 
    $actionName = $request->getActionName(); 

    $controller = new $controllerName(); 
    $controller->$actionName(); 

} 
+0

感谢 - 该解决方案使得比我如何努力做很多更有意义。但是,有一件事,如果你可以详细阐述一下 - 如果你不能重置HTTP头文件,你会如何将参数附加到forward方法,我感到困惑。或者它曾经是一个集合,那有什么好处呢? –

+0

@AdrianNorman我更新了一些答案,我希望它有道理。最好的办法是查看控制器和调度程序的代码以获得更好的想法。 – AlexP

+0

非常感谢你的阐述 - 为Zend_Controller_Request_Http对象清理了很多东西。 –

0

在else块:

$this->_redirect($this->url(array('login' => $formData['username'], 'nameOfYourRoute')); 

增添了新的变数弄“登录”到你的路线并填充表格登录这个变量。