Search code examples
phpcakephpresponse

CakePHP response send is empty


I am trying to create some generic return functions in CakePHP 2.5.3 to standardise the resposnes. I am using Router::parseExtensions('json', 'xml');

protected function returnSuccess($data = null, $message = 'Success', $extraSerialize = array(), $statusCode = 200) {
    $this->set(array(
        'status' => true,
        'data' => $data,
        'message' => $message,
        '_serialize' => array_merge(array('status', 'data', 'message'), $extraSerialize)
    ));

    $this->response->statusCode($statusCode);
    $this->response->send();
    $this->_stop();
}


protected function returnError($data = null, $message = 'Error', $extraSerialize = array(), $statusCode = 400) {
    $this->set(array(
        'status' => false,
        'data' => $data,
        'message' => $message,
        '_serialize' => array_merge(array('status', 'data', 'message'), $extraSerialize)
    ));

    $this->response->statusCode($statusCode);
    $this->response->send();
    $this->_stop();
}

However the response is always empty. If I remove $this->_stop(); than it works. However I would like the to stop the request then (especially on error).


Solution

  • You are aborting before the view is even being rendered, so that's the expected behavior.

    Your CakeResponse::send() call actually has no effect (apart from possible headers being sent), and the only reason this is not causing an error is because the body that is being echoed is empty at that time, otherwise you'd receive a "headers already sent" error when Cake outputs the rendered data.

    Personally I'd probably use exceptions instead of this manual sending/aborting stuff, something like

    if(!$abc) {
        throw new ForbiddenException();
    }
    
    // ...
    

    or a simple return

    if(!$abc) {
        return $this->returnError();
    }
    
    // ...
    

    where returnError() returns $this->response. Both would make invoking send() and _stop() unnecessary.

    However, it's of course also possible to manually invoke view rendering

    protected function returnError($data = null, $message = 'Error', $extraSerialize = array(), $statusCode = 400) {
        // ...
    
        $this->render();
    
        $this->response->statusCode($statusCode);
        $this->response->send();
        $this->_stop();
    }
    

    that way a proper body would be set for the response.

    See also