TIP: FirePHP data volume filtering
October 15, 2010

FirePHP is most often used for ad hock logging of variables during development by placing logging calls at strategic places in your code.

$someVariable = 'Some value';
 
// using FirePHPCore
$firephp = FirePHP::getInstance(true);
$firephp->log($someVariable);
 
// using Zend_Log_Writer_Firebug
$logger = new Zend_Log(new Zend_Log_Writer_Firebug());
$logger->log($someVariable, Zend_Log::DEBUG);

This works well for variables that contain small amounts of data. String, boolean and integer values are typically small and do not require much consideration. Array and object values may contain a lot more data as FirePHP traverses them (all array elements and object members) until the complete or maximum depth is reached. This is also true when logging exceptions and traces where all function and method arguments are also traversed. The data volume can quickly grow to megabytes which has fatal consequences for transmission of the debug data to the client and the client being able to render it.

FirePHP includes some solutions to these problem that you can take advantage of.

FirePHPCore

The FirePHPCore API includes a way to set the maximum traversal depth and allows for filtering of unwanted members on objects.

NOTE: These features are available as of FirePHPCore 0.3.2

$deepArray = array('A', array('very' => array('deep', array('array'))));
$deepObject = new DeepObject(); // contains member references to other objects
$mixedVariable = array('An', array('array that contains an object' => $deepObject));
 
// log arrays up to a maximum depth
$firephp->setOption('maxArrayDepth', 2);
$firephp->log($deepArray);
 
// log objects up to a maximum depth
$firephp->setOption('maxObjectDepth', 2);
$firephp->log($deepObject);
 
// when a variable is logged that contains arrays and objects in the graph
// the array and object depth is reset whenever a new type is encountered.
// use the following to set a maximum total depth
$firephp->setOption('maxDepth', 2);
$firephp->log($mixedVariable);

Rather than restricting the depth of an object logged you can also filter out certain class members. This is useful if there are certain members that are of no interest to you during debugging while you want to preserve others to full depth.

$firephp->setObjectFilter('DeepObject', array('MemberName'));
$firephp->setObjectFilter('DeepObject2', array('MemberName', 'AnotherMember'));

So when logging exceptions or traces you can use the following to significantly trim the volume of data.

$previousOptions =  $firephp->getOptions();
$firephp->setOption('maxDepth', 1);
 
$firephp->trace('Trace to here');
try {
    throw new Exception('Test Exception');
} catch(Exception $e) {
    $firephp->error($e);
}
 
// reset options to previous values
$firephp->setOptions($previousOptions);

Zend_Log_Writer_Firebug

Some of the same options are available with Zend_Log_Writer_Firebug even though they are not documented. Until documentation is available you can take a look at the source code for supported methods and options.

$firephp = Zend_Wildfire_Plugin_FirePhp::getInstance();
 
$firephp->setOption('maxObjectDepth', 2);
$firephp->setOption('maxArrayDepth', 2);
// NOTE: maxDepth is not supported at this time (ZF-10562)
 
// an additional option not supported by FirePHPCore which sets
// the maximum number of frames to include for traces and exceptions
$firephp->setOption('maxTraceDepth', 5);
 
// object member filtering
$firephp->setObjectFilter('DeepObject2', array('MemberName', 'AnotherMember'));

FirePHP 1.0

FirePHP 1.0 is in BETA and provides much more detailed control over how variables are traversed. You can upgrade to FirePHP 1.0 which is completely backwards compatible with the FirePHPCore library. Once you have verified that your existing code still works as before you can upgrade your your inclusion method and use the new Insight API.

// select the 'page' context and get the console (i.e. the Firebug Console)
$inspector = FirePHP::to('page');
$console = $inspector->console();
 
// override some options if applicable (defaults are shown)
$console = $console->options(array(
    'encoder.depthNoLimit' => false,
    'encoder.lengthNoLimit' => false,
    'encoder.maxDepth' => 5,
    'encoder.maxArrayDepth' => 3,
    'encoder.maxArrayLength' => 25,
    'encoder.maxObjectDepth' => 3,
    'encoder.maxObjectLength' => 25,
    'encoder.trace.maxLength' => -1,  // no maximum
    'encoder.exception.traceMaxLength' => -1  // no maximum
));
// the $console object now has the new options set
 
// class member filtering
$console = $console->filter(array(
    'classes' => array(
        '<ClassName>' => array('<MemberName>')
    )
));
// the $console object now also has the class member filter set
 
// log to the console
$console->log($mixedVariable');

For more information see the Insight API documentation or read up on FirePHP 1.0 here.

Summary

FirePHP is evolving into a complete debugging solution that must be flexible enough to cover all use cases. If you are using FirePHP and run into something that you believe it should handle please speak up. The FirePHP community will thank you for it.

You can follow FirePHP tips, news and happenings on twitter.

1 Comment
Halil
February 20, 2011

Thanks for the information. It’s much better to set it from the beginning instead of waiting long seconds for the browser to respond (or worse, crash).





Linkbacks