2

我有一个带有editAction().

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');
           }
       }
   }
}

如何停止控制器执行?

4

2 回答 2

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
        }
    }
}
于 2011-07-22T18:41:15.087 回答
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。

于 2011-07-22T19:43:17.570 回答