开发者

Is it possible in Cakephp it intercept a no action found event and handle it in the controller?

开发者 https://www.devze.com 2023-04-01 08:17 出处:网络
I would like to handle a missing action in one of my controllers in a default action. Now the default behavior is to throw an error. I would like to be able to have a default action in that controller

I would like to handle a missing action in one of my controllers in a default action. Now the default behavior is to throw an error. I would like to be able to have a default action in that controller that is called and passed the name of the action requested so I may do something with it. Now I know you can change the whole missing action page which开发者_开发问答 is not what I am looking to do. Any incite on this would be great, if its not possible please let me know.

Thanks


Depending on how much of an exception to your normal actions this is, a change in routing may make more sense:

Router::connect('/mycontroller/*',
                array('controller' => 'mycontroller', 'action' => 'catchall'));

If you have some normal actions in that controller, define a route for them before this catch-all route to have them handled normally.

If you really want to futz around with the action handling in the controller itself, you should be able to do so in beforeFilter:

public function beforeFilter() {
    if (!method_exists($this, $this->action)) {
        unshift($this->params['pass'], $this->action);
        $this->action = 'catchall';
    }
}

Something like that at least, that's just a quick untested idea.


I ran into the same problem. I had to prevent the default HTML error page for a JSON-responding controller.

The way @deceze suggested didn't work for me for some different reasons:

  1. After routing with the wildcard to a specific action, the invoked action is always the one you defined in routes.php. BUT the action from the URI is passed as the first argument.
  2. You cannot overwrite $this->action, but you can use $this->setAction()

What I did:

  1. Route all calls to a specific action

    Router::connect('/ajax/*', array('controller' => 'ajax', 'action' => 'handle'));
    
  2. Parse the call in this action

    public function beforeFilter() {
        $this->autoRender = false;
    }
    
    public function index($arg1 = false) {
        return new CakeResponse(array('body' => json_encode(array('foo' => $arg1))));
    }
    
    public function handle($action = '') {
        if (method_exists($this, $action)) {
            return call_user_func_array(array($this,'setAction'),  func_get_args());
        } else {
            return $this->_error();
        }
    }
    
    private function _error() {
        return new CakeResponse(array('body' => json_encode(array('status' => 'error'))));
    }
    

Hope this will helpful for someone.

0

精彩评论

暂无评论...
验证码 换一张
取 消