Zend Framework:如何停止调度/控制器执行?

时间:2011-07-22 18:22:20

标签: ajax zend-framework zend-controller

我有一个带editAction()的Zend Framework控制器。

class WidgetController extends BaseController
{
   public function editAction()
   {
       //code here
   }
}

此控制器扩展了一个基本控制器,用于在允许用户编辑记录之前检查用户是否已登录。

class BaseController extends Zend_Controller_Action
{
   public function init()
   {
       if ($this->userNotLoggedIn()) {
           return $this->_redirect('/auth/login');
       }
   }
}

但是,现在我正在执行AJAX请求,我将重新发送JSON响应,因此重定向将不再起作用。我需要停止进一步的控制器执行,这样我才能立即发送响应:

class BaseController extends Zend_Controller_Action
{
   public function init()
   {
       if ($this->userNotLoggedIn()) {
           if ($this->_request->isXmlHttpRequest()) {
               $jsonData = Zend_Json::encode(array('error'=>'You are not logged in!'));
               $this->getResponse()
                    ->setHttpResponseCode(401)
                    ->setBody($jsonData)
                    ->setHeader('Content-Type', 'text/json');
               //now stop controller execution so that the WidgetController does not continue
           } else {
               return $this->_redirect('/auth/login');
           }
       }
   }
}

如何停止执行控制器?

2 个答案:

答案 0 :(得分:5)

我会定义用户没有登录并尝试将XMLHTTPRequest作为异常状态,让错误处理程序通过抛出异常(停止调度当前操作)来处理它。这样,您还可以处理可能发生的其他类型的异常:

class BaseController extends Zend_Controller_Action
{
   public function init()
   {
       if ($this->userNotLoggedIn()) {
           if ($this->_request->isXmlHttpRequest()) {
                throw new Exception('You are not logged in', 401);
           } else {
               return $this->_redirect('/auth/login');
           }
       }
   }
}

class ErrorController extends Zend_Controller_Action
{

    public function errorAction()
    {
        $errors = $this->_getParam('error_handler');
        $exception = $errors->exception;

       if ($this->_request->isXmlHttpRequest()) {
           $jsonData = Zend_Json::encode($exception);
            $jsonData = Zend_Json::encode(array('error'=> $exception->getMessage()));
            $isHttpError = $exception->getCode() > 400 && $exception->getCode();
            $code =  $isHttpError ? $exception->getCode() : 500;
           $this->getResponse()
                ->setHttpResponseCode($code)
                ->setBody($jsonData)
                ->setHeader('Content-Type', 'application/json');
        } else {
            // Render error view
        }
    }
}

答案 1 :(得分:5)

我可以想到许多方法可以在代码中停止控制器。

//now stop controller execution so that the WidgetController does not continue

首先,您可以使用以下内容替换该行:

$this->getResponse()->sendResponse();
exit;

这可能不是最干净但可以很好地完成工作。另一种选择是在init中更改请求的操作,并让另一个操作处理它。用这个替换该行:

 $this->getRequest()->setActionName('invalid-user');

因为您已经在调度程序内部,所以无论您是否想要它,它都会在您的操作类中运行一个操作。尝试在preDispatch中更改请求将不会更改此调度。此时已确定在您的课程中执行操作。所以,做一个动作来处理它。

public function invalidUserAction()
{
    $this->_helper->layout->disableLayout();
    $this->_helper->viewRenderer->setNoRender();
}

有关更多信息,请参阅Zend_Controller_Dispatcher_Standard :: dispatch。