在Zend_Controller_Action::init()
期间,是否有办法取消操作(因此不会调用它)?
<?php
class JsonApiController extends Zend_Controller_Action {
function init()
{
// try JSON decoding the raw request body
if ($jsonDecodingFailed) {
echo '{"error":"invalid JSON"}';
$this->_cancelAction(); // something like this exist?
}
}
}
我目前的解决方法是制作一个空的nullAction()
方法并致电$this->_forward('null')
转发给它。
答案 0 :(得分:2)
在init()中使用$ this-&gt; _forward()没有错(如果要转发的方法与init()在同一个控制器内),这只会改变请求对象的控制器/ action(覆盖通过路由器设置的内容)。
另一种方法是创建一个Zend_Controller_Plugin,因为它看起来像是在处理意外错误。 看看Zend_Controller_Plugin_ErrorHandler实现。 因此,如果响应包含eny预测,并且只是编辑当前的Request对象以显示“取消”操作,则不会转发到另一个操作,而是抛出异常,并在postDispatch()中检查自定义插件。
$request->setDispatched(false)
->setControllerName("error")
->setActionName("jsonDecoding");
最后一种方法可能是在echo“{error:”invalid json“}”之后抛出一个出口“不是很好但是你会避免重载另一个调度迭代。
答案 1 :(得分:2)
我会抛出异常(然后在错误控制器中捕获它) - 这就是当存在不可恢复的错误时你所做的事情。
答案 2 :(得分:2)
也许试试这个:
$this->_helper->viewRenderer->setNoRender();
return;
答案 3 :(得分:1)
对于仍在寻找解决方案的人,您可以尝试这样做:
添加一个标志,指出是否存在错误,并覆盖调度方法。如果设置了标志,请不要调用parent::dispatch
。
这是我想要的方式。我的理由是我正在制作一个抽象的API控制器,默认情况下会检查请求中的API密钥,如果不存在 - 控制器应该响应错误并成功完成请求。
E.g。
abstract class Api_Controller extends Zend_Rest_Controller{
private $responded = false;
public function init() {
parent::init();
if(!$this->isKeyValid())
$this->respond("invalid key"); // this would set flag to true and handle error
}
public function dispatch($action) {
// if an error occured and it was dispatched, do not call action method, just finish request
if(!$this->responded)
parent::dispatch($action);
}
}
对我而言,这似乎是一个干净的解决方案。
答案 4 :(得分:0)
根据documentation(在“调度前和发送后挂钩”下),在preDispatch()中调用_forward()将跳过该操作。
特别是关于preDispatch():“它的主要目的是决定是否应该调度所请求的操作。如果没有,你应该_forward()到另一个动作,或抛出异常。”