I just discovered FirePHP today (via a discussion at PHPBuilder.com), a set of PHP classes along with a Firefox add-on which allows you to debug your PHP scripts through the Firebug console (a separate Firefox add-on you’ll also need to install if you haven’t already done so).
Essentially, what it does is allow your PHP server-side scripts to output debug information to your browser via a set of HTTP headers which are then intercepted and displayed by the Firebug console window. This way, instead of doing a var_dump() or print_r() to view a variable or object in the middle of your HTML output (or routing it to a log file on the server), you can view that info separately in the Firebug window.
Here’s a quick example of the most basic usage:

Strip Comments and White-Space from PHP File
Inspired by a number of web forum “conversations,” I decided to make a little tool for stripping PHP comments from files as well as blank lines and leading white-space. This is for any of you who feel you need to save a few nano-seconds when processing PHP files, or maybe want to do a little elementary code obfuscation. The main work is done by the built-in PHP tokenizer functions.
Enjoy
<?php /** * Strip comments out of PHP files * * Derived from code example at http://www.php.net/tokenizer * * Sample usage: * dir_strip_comments(getcwd(), 'test'); */ /** * T_ML_COMMENT does not exist in PHP 5. * The following three lines define it in order to * preserve backwards compatibility. * * The next two lines define the PHP 5 only T_DOC_COMMENT, * which we will mask as T_ML_COMMENT for PHP 4. */ if (!defined('T_ML_COMMENT')) { define('T_ML_COMMENT', T_COMMENT); } else { define('T_DOC_COMMENT', T_ML_COMMENT); } /** * Strip PHP comments from supplied source code string * * Also strips out blank lines and leading white-space * @param string $source * @return string */ function strip_comments($source) { $tokens = token_get_all($source); $result = ''; foreach ($tokens as $token) { if (is_string($token)) { // simple 1-character token $result .= $token; } else { // token array list($id, $text) = $token; switch ($id) { case T_COMMENT: case T_ML_COMMENT: // we've defined this case T_DOC_COMMENT: // and this // no action on comments break; default: // anything else -> output "as is" $result .= $text; break; } } } return $result; } /** * Strip comments from specified file, writing to specified directory * * @param string $file * @param string $dir */ function file_strip_comments($file, $dir=null) { if($dir === null) { $dir = getcwd(); } $target = $dir . DIRECTORY_SEPARATOR . basename($file); $source = file_get_contents($file); if($source === false) { user_error("Unable to read file '$file'"); return false; } $source = strip_comments(trim($source)); $source = preg_replace('#[\r\n]\s+#', "\n", $source); $result = file_put_contents($target, $source); if($result === false) { user_error("Unable to write to file '$target'"); } return $result; } /** * Strip comments from PHP files in directory * * @param string $sourceDir * @param string $targetDir * @param string $ext */ function dir_strip_comments($sourceDir=null, $targetDir=null, $ext='php') { if($sourceDir === null) { $sourceDir = getcwd(); } if($targetDir === null) { $targetDir = getcwd(); } $files = glob($sourceDir . DIRECTORY_SEPARATOR . "*.$ext"); foreach($files as $file) { $result = file_strip_comments($file, $targetDir); if($result) { echo "Wrote: " . $targetDir . DIRECTORY_SEPARATOR . basename($file); } else { echo "ERROR: did not write $file"; } echo "<br>\n"; } } ?>