I'm a pretty visual person and I like to see all the cool information about objects, arrays and different variables in PHP. In the beginning I would just echo '<pre>', var_dump($var), '</pre>';
liberally throughout my code. Then I was introduced to MVC and started grasping the concept of OOP and the Front Controller design pattern. Now, after having built my own little personal framework for academic reasons and understanding the need for reusable code a little part of my soul is eaten away every time I have to manually type this out.
This was my attempt at an OOP-style debugger that will spit out various information about the passed variable. The debug()
method is the only public
method and it takes two parameters, 1 being the variable you want to know more about and the other an optional boolean
, default true
, to toggle echoing a message to Firebug/Webkit Inspector console or straight to the browser screen.
My question is: Does this look horribly bad? Are there ways that my code can be improved? Is my logic illogical?
/**
* Returns useful information about variables or objects for debugging purposes
*
* @package sprayfire
* @subpackage core
*/
class SprayFireDebugger {
/**
* The original variable that needs to be debugged
*
* @var mixed
*/
private $_debugVar;
/**
* True if the debug message should be sent to console.log and false if it
* doesn't
*
* @var bool
*/
private $_doConsoleLog;
/**
* The final message that should be echod
*
* @var mixed
*/
private $_debugMessage;
/**
* SprayFireDebugger should never rely on __construct dependencies
*
* @return void
*/
public function __construct() {
}
/**
* Will emit useful information about the given variable. If the second
* parameter is set to false the message gets displayed on the screen
* as compared to the debug console
*
* @param mixed $var
* @param bool $toJsConsole
* @return void
*/
public function debug($var, $toJsConsole = true) {
try {
$this->_debugVar = $var;
$this->_doConsoleLog = $toJsConsole;
if (is_object($this->_debugVar)) {
$this->_debugObject();
} else {
$this->_debugMessage = $this->_debugVar;
}
$this->_send();
$this->_cleanUpDebug();
return true;
} catch (Exception $Exception) {
// here to catch exceptions from _debugObject()
error_log($Exception->__toString());
$this->_cleanUpDebug();
return false;
}
}
/**
* Will determine if an object is an exception or not and return
* appropriate information for an object
*
* @return void
*/
private function _debugObject() {
$exc = 'Exception';
$Reflection = new ReflectionClass($this->_debugVar);
if ($Reflection->getName() === $exc) {
return $this->_debugException();
}
if ($Reflection->getParentClass()) {
if ($Reflection->getParentClass()->getName() === $exc) {
return $this->_debugException();
}
}
$debugInfo = $Reflection->export($this->_debugVar, true);
$this->_debugMessage = $debugInfo;
return;
}
/**
* Takes an Exception object and turns it into an appropriate array to
* be sent to the console or screen
*
* @return void
*/
private function _debugException() {
$debugInfo = array(
'message' => $this->_debugVar->getMessage(),
'code' => $this->_debugVar->getCode(),
'file' => $this->_debugVar->getFile(),
'line' => $this->_debugVar->getLine(),
'trace' => $this->_debugVar->getTrace()
);
$this->_debugMessage = $debugInfo;
return;
}
/**
* Sends $this->_debugMessage to the screen or a JS console
*
* @return void
*/
private function _send() {
if ($this->_doConsoleLog) {
$this->_sendToConsole();
} else {
$this->_sendToScreen();
}
if (empty($this->_debugMessage)) {
throw new Exception('There was no error message to show. This likely means something is royally messed up!', E_USER_ERROR);
}
echo $this->_debugMessage;
return true;
}
/**
* Echos out a script that logs a JSON ecoded $this->_debugMessage in the
* browser console window. If you are testing with IE please ensure you
* pass false to $this->debug()
*
* @return void
*/
private function _sendToConsole() {
$consoleMsgMarkup = '<p style="position: absolute; bottom: 0; right: 1em;" class="sprayfire-debug-message">Debug info sent to console!</p>';
$scriptMarkup = '<script type="text/javascript">';
$scriptMarkup .= 'console.log(' . json_encode($this->_debugMessage) . ')';
$scriptMarkup .= '</script>';
$this->_debugMessage = $consoleMsgMarkup . $scriptMarkup;
return;
}
/**
* Echo the message to the main browser window
*
* @return void
*/
private function _sendToScreen() {
ob_start();
var_dump($this->_debugMessage);
$varDump = ob_get_clean();
if (!$varDump) {
throw new Exception('The output buffer was not initiated for dumping to the screen!', E_USER_ERROR);
}
$screenMarkup = '<pre>' . $varDump . '</pre>';
$this->_debugMessage = $screenMarkup;
return;
}
/**
* Reset the class properties to be ready for the next debug call
*
* @return void
*/
private function _cleanUpDebug() {
$this->_debugVar = NULL;
$this->_doConsoleLog = NULL;
$this->_debugMessage = NULL;
return;
}
}
// End SprayFireDebugger
The code appears to work right, but I'm also a solo-developer with no kind of peer review. I guess I don't know what I don't know. Thanks for taking a look, I appreciate any feedback.