我可以在init()方法中取消Zend Controller操作吗?

时间:2010-10-19 17:33:12

标签: php model-view-controller zend-framework controller

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')转发给它。

5 个答案:

答案 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()到另一个动作,或抛出异常。”