The DebugHandler class is registered as a service called Debug. It is available for easily outputting text or data to the web browser in order to help debug your program during runtime. Any experienced PHP programmer has surely debugged their code by inserting "meaningful" print commands in their code. This is very ugly, and you may never even see the printed text depending on where in your logic is appears.
The DebugHandler catches all of your debug output calls, keeping track of what file, function, class, line number and arguments produced the call. This way, when you output your debug content it will appear in one informative block (even in a separate window), showing your when the call was made and from what file, etc.
Like many classes in Harmoni, the DebugHandler class is separate from DebugHandlerPrinter classes, allowing you to choose how to output your debug content whenever you want, even outputting it to multiple locations. For example, you might want to print things to your browser, but also to a file in case a broken HTML tag hides all of your outputted content.
Included in Harmoni are two printers: PlainTextDebugHandlerPrinter and the NewWindowDebugHandlerPrinter. The former prints right to the browser window in a very simple HTML layout. The latter is much more useful and outputs to a separate "Debug Output" window with nice formatting and color coded debug levels.
The following sections will let you know how to take advantage of the DebugHandler
$debug =& Services::requireService("Debug");
// any of the following blocks will work
$debug->add("We are testing debug output.", 10, "test");
// or
$debug->add( new DebugItem(
"We are testing debug output.",
10,
"test"));
The above examples both have exactly the same effect. The arguments to add() are:
-
The debug text (can be anything)
The debug level - specifies the "severity" or how "low-level" the output is. I use it to specify how deep into code logic we are. For example, API classes that actually talk to databases and such get a pretty high number (in the 5-10 range). Harmoni system debug calls get even higher numbers, etc.
The category - use it however you want. It is there purely as a means of organization, or to group debug output from a single method or class. If you leave this argument off, the category will default to "general".
To make choosing a debug output level easier, we have supplied 15 pre-defined constants:
-
DEBUG_USER[1-5] - the lowest numbers, meant for use by front-end debug output (the scripts that output UI to the browser, for example).
DEBUG_API[1-5] - mid-range numbers, meant for use by back-end debug output (scripts that interface with database or other storage mechanisms).
DEBUG_SYS[1-5] - the higher numbers, meant for use by the Harmoni system alone. If you ever want to see all of what Harmoni is doing, set your output level to DEBUG_SYS5
To output the debug content, you need to choose a printer, or write your own. The DebugHandlerPrinterInterface class is provided to show you what methods are required of any printer class. You can look at the existing ones for ideas. Once you have chosen a printer (let's take the PlainTextDebugHandlerPrinter). This code will output all content in the category "test" with level smaller than or equal to 10:
$debug =& Services::requireService("Debug");
PlainTextDebugHandlerPrinter::printDebugHandler($debug, 10, "test");
The second two arguments to printDebugHandler are optional. By leaving the category off ("test" in this example), items will be printed no matter the category. Leaving off the debug level (10 in this example) or setting it to null will make the printer ask the DebugHandler what level it is set to accept (see the next section) and printer everything under that.
The two functions: DebugHandler::setOutputLevel($level) and DebugHandler::getOutputLevel() allow you to set or get the pre-defined output level for the handler. This is useful for two reasons: by setting the output level on the handler, you can save yourself a lot of processing time - instead of storing ALL the debug text and backtrace information, the handler will discard any that it won't be printing later. This way, when you release your software and set the level to 0, the handler will discard everything, resulting in no processing overhead. Second, you can set the level somewhere early in your code (like in a config file) and have the printer use that value.
Along with the Debug service there is a wrapper class: debug. This is a static class that allows you to set/get the debug output level and output new text with just one line of code. Here is how to use it:
// some code
debug::output("We are here! At the place!!",7, "test");
// and
print "Currently, the debug level is: " . debug::level();
print "Setting it to 10...";
debug::level(10);
print "It is now " . debug::level();
// and now, print out all the output
debug::printAll();
// will print debug output to a new popup window (using the NewWindowDebugHandlerPrinter class)
It is important to remember that you must set the debug level (debug::level(n);) before outputting, since any output to a level higher than the set level will be ignored.