vvs.harsha
vvs.harsha

Reputation: 33

Zend _forward() does not work in preDispatch()?

Im currently building a controller from my Zend MVC application which would only be used as json service to populate the page. I want to restrict the users to use only GET method to access this end point(for some security reasons).

I followed this post _forward() in Zend does not work? but could not get working.

I am using the preDispatch to detect the non-get requests and would like to forward to errorAction in the same controller. My code looks likes this,

public function preDispatch(){
    $this->_helper->layout()->disableLayout();
    $this->_helper->viewRenderer->setNoRender();
    //Restrict this Controller access to Http GET method
    if(!($this->getRequest()->isGet())){
        return $this->_forward('error');
    }
}

public function errorAction(){
    $this->getResponse()->setHttpResponseCode(501);
    echo "Requested Method is not Implemented";
}

When I test the page with a post request, it throws

PHP Fatal error: Maximum execution time of 30 seconds exceeded

I got it working with

$this->_redirect("service/error");

Wondering if it is the only/best way to handle this situation.

Any help would be really appreciated. Thanks in advance.

Upvotes: 2

Views: 1038

Answers (1)

drew010
drew010

Reputation: 69967

The reason that calling _forward doesn't work is because the request method doesn't change so you end up in an infinite loop trying to forward to the error action since the request is always POST.

_forward works by modifying the module, controller, and action that will be called when the request is dispatched, _redirect actually returns a 302 redirect and results in an additional HTTP request by the browser.

Either method is okay, but I'd prefer to go with _forward since it won't require an additional HTTP request (but you still guarantee the POST request is denied).

This code should work for you:

    if(!($this->getRequest()->isGet())){
        // change the request method - this only changes internally
        $_SERVER['REQUEST_METHOD'] = 'GET';

        // forward the request to the error action - preDispatch is called again
        $this->_forward('error');

        // This is an alternate to using _forward, but is virtually the same
        // You still need to override $_SERVER['REQUEST_METHOD'] to do this
        $this->getRequest()
             ->setActionName('error')
             ->setDispatched(false);
    }

Upvotes: 2

Related Questions