代码之家  ›  专栏  ›  技术社区  ›  Steve Clay

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

  •  6
  • Steve Clay  · 技术社区  · 15 年前

    在 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 回复  |  直到 15 年前
        1
  •  2
  •   Mads Lee Jensen    15 年前

    在init()内使用$this->_forward()没有任何错误(如果要转发的方法与init()在同一控制器内),这只会更改请求对象的控制器/操作(覆盖通过路由器设置的内容)。

    另一种方法是创建一个Zend_Controller_插件,因为它看起来像是在处理意外错误。 因此,如果响应包含eny expections,并且只是编辑当前请求对象以显示“取消”操作,那么您将抛出一个异常,并让您的自定义插件签入postDispatch(),而不是转发到另一个操作。

    $request->setDispatched(false)
            ->setControllerName("error")
            ->setActionName("jsonDecoding");
    

    最后一种方法可能是在echo“{error:”invalid json“}”之后抛出一个出口,这不太好,但可以避免再次分派迭代的过载。

        2
  •  2
  •   TomáÅ¡ Fejfar    15 年前

    我会抛出一个异常(然后在错误控制器中捕获它)-这就是当存在不可恢复的错误时所做的。

        3
  •  2
  •   Jason Plank Maksim Kondratyuk    14 年前

    $this->_helper->viewRenderer->setNoRender();
    return;
    
        4
  •  1
  •   Echilon Mafarnakus    13 年前

    对于仍在寻找解决方案的人,可以尝试以下操作: 添加一个标志,说明是否存在错误,并重写分派方法。如果设置了标志,则不要调用 parent::dispatch

    这是我想要的方式。我的原因是,我正在制作一个抽象的API控制器,默认情况下,它会检查请求中的API密钥,如果它不在那里,那么控制器应该以错误响应并成功完成请求。

    例如。

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

    对我来说,这似乎是一个干净的解决方案。

        5
  •  0
  •   jackocnr    15 年前

    documentation (在“调度前和调度后挂钩”下),在Pre Dispatch()中调用_forward()将跳过该操作。