CakePHP + FirePHP

I was poking through the addons for Firebug today, and liked the look of FirePHP, so I started looking into how I could use it. As many of you know, I’m a big fan of CakePHP as a framework, so I looked up how to integrate the two together and make them work nicely. I found this guide on the Cake Bakery, and followed it with a few modifications, so here they are.

First, the requirements:

  • Firefox 3+
  • Firebug
  • FirePHP Extension
  • FirePHP Core Library (I installed this from pear)

Copy dbo_source.php (found in cake/lib/models/datasources) from Cake’s core to app/models/datasources/ in your app, and then open it, and find the showLog() function. Replace it with this:

function showLog($sorted = false) {
	if ($sorted) {
		$log = sortByKey($this->_queriesLog, 'took', 'desc', SORT_NUMERIC);
	} else {
		$log = $this->_queriesLog;
	}
 
	if ($this->_queriesCnt > 1) {
		$text = 'queries';
	} else {
		$text = 'query';
	}
 
	if (PHP_SAPI != 'cli') {
		$summary = "{$this->_queriesCnt} {$text} took {$this->_queriesTime} ms";
 
		$body = array();
		$body[] = array("Nr", "Query", "Error", "Affected", "Num. rows", "Took (ms)");
		foreach ($log as $k => $i) {
			$body[] = array(($k + 1), $i['query'], $i['error'], $i['affected'], $i['numRows'], $i['took']);
		}
 
		fb(array($summary, $body), FirePHP::TABLE);
	} else {
		foreach ($log as $k => $i) {
			print (($k + 1) . ". {$i['query']} {$i['error']}\n");
		}
	}
}

Then add the following to your app/config/bootstrap.php:

require_once('FirePHPCore/FirePHP.class.php');
 
function fb() {
	$debug = Configure::read('debug');
	if ($debug) {
		$ob_setting = ini_get('output_buffering');
		if (!$ob_setting) {
			ob_start();
		}
 
		$instance = FirePHP::getInstance(true);
		$args = func_get_args();
		return call_user_func_array(array($instance, 'fb'), $args);
	} else {
		return true;
	}
}

Finally, create a new component: app/controllers/components/fire_p_h_p.php (I named the file like this, so that the name in code is FirePHP, which I think looks better than FirePhp. Php has always looked wrong to me.) with these contents:

class FirePHPComponent {
	private $instance;
 
	public function __construct() {
		$ob_setting = ini_get('output_buffering');
		if (!$ob_setting) {
			ob_start();
		}
		$this->instance = FirePHP::getInstance(true);
		$this->instance->setEnabled(Configure::read('debug'));
	}
 
	public function __call($name, $args) {
		return call_user_func_array(array($this->instance, $name), $args);
	}
}

Now you can access FirePHP by adding the FirePHP component to your controller, and calling the regulare FirePHP methods, like this:

class FirephpController extends AppController {
	var $components = array('FirePHP');
 
	public function debug() {
		$this->FirePHP->error('some error');
	}
}

My thanks to Tobias Funke and Marwin at the Bakery for the article and comments that helped me get this all set up. It works beautifully, and will greatly improve my productivity going forward.

%d bloggers like this: