ZF-4134: Zend_Controller_Action_Helper_Json->sendJson() blocks front's dispatchLoopShutdown()



 * Simplify AJAX context switching based on requested format
class Zend_Controller_Action_Helper_Json extends Zend_Controller_Action_Helper_Abstract
    // Suppress exit when sendJson() called
    public $suppressExit = false;

    // Encode JSON response and immediately send
    public function sendJson($data, $keepLayouts = false)
        $data = $this->encodeJson($data, $keepLayouts);
        $response = $this->getResponse();

        if (!$this->suppressExit) {

        return $data;

Everything's ok here only if we assume that no controller plugin adds http headers to Zend_Controller_Response. Otherwise, we get lack of expected headers inserted by FC's plugins.

For example, one of this affected plugin is Zend_Wildfire_Channel_HttpHeaders (extends Zend_Controller_Plugin_Abstract) which inserts firephp-related headers with its flush() method initially triggered by "_plugins->dispatchLoopShutdown()" in front controller.

h3.Test case Zend_Registry::get('log') returns Zend_Logger object with firebug writer.


Zend_Registry::get('log')->info('Test debug msg...'); // WILL send firebug headers

h4.Doesn't work

Zend_Registry::get('log')->info('Test debug msg...'); // Will NOT send firebug headers

h3. Temporary Workaround for Zend_Wildfire_Channel_HttpHeaders

$json = $this->getHelper('Json');
$json->suppressExit = true;


For Zend_Wildfire_Channel_HttpHeaders, the problem could be solved by registering a listener/plugin on Zend_Controller_Response that gets notified when sendResponse() or more specifically sendHeaders() is called. This would work for any other plugins that need to send headers as well.

See ZF-4181 for another reason for needing a listener for sendHeaders() for the Response object.

Also reported here: ZF-4202

Marked as won't fix for the following reasons:

  1. The helper explicitly notes that it's purpose it to immediately send the response when called sendJson().
  2. I can see two possible solutions for deferring the immediate sending using the sendJson() and direct() methods to return the JSON without calling sendResponse().

It appears that the issue is not a bug but a disagreement over the nature/API of the helper. Such disagreements do not constitute a valid issue.