我有一个带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');
}
}
}
}
如何停止执行控制器?
答案 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。