How to use Firebug to Debug PHP Scripts

We usually use Firebug to debug Javascript, AJAX and so on, so here is how to use Firebug to debug your PHP scripts. I have written long time ago a PHP class Buggy to help me store debug information in database so it could be better analyzed later. Now that many are using Firebug, I […]

We usually use Firebug to debug Javascript, AJAX and so on, so here is how to use Firebug to debug your PHP scripts. I have written long time ago a PHP class Buggy to help me store debug information in database so it could be better analyzed later. Now that many are using Firebug, I find it pretty interesting to have such debug information available directly in Firebug so you can group both server-side and client-side debug info in a single place.

Last week I saw FirePHP, which introduce a specific protocol to help debugging PHP scripts and add a new tab to FireBug to visualize results. Here is a fast way to create your own debug solution and use Firebug itself to visualize these informations.

The solution is in reality inspired from FirePHP and my old Buggy PHP class, but more simplified to track time consumption in your code :

/**  
 * Buggy inside Firebug - Simply  
 *   
 * @package GONX  
 * @author hatem <hatem at php dot net>  
 * @website http://phpmagazine.net  
 * @copyright Copyright (c) 2005-2007  
 * @version $Id: buggy.class.php,v 2.1 2007/02/10 03:50:12 hatem Exp $  
 * @access public  
 **/   
class buggy {   
    /**  
     * Buggy::getmicrotime()  
     *   
     * @return   
     **/   
    function getmicrotime(){   
        $mtime = microtime();   
        $mtime = explode(" ",$mtime);   
        $mtime = $mtime[1] + $mtime[0];   
        return ($mtime);   
    }   
  
    /**  
     * Buggy::SetMicroTime()  
     *   
     * @param $module  
     * @return   
     **/   
    function SetMicroTime($module)   
    {   
        global $Buggy;   
        $Buggy[$module] = Buggy::getmicrotime();   
        return $Buggy[$module];   
    }   
       
    /**  
     * Buggy::GetExecutionTime()  
     *   
     * @param $module  
     * @return   
     **/   
    function GetExecutionTime($module)   
    {   
        global $Buggy;   
        $end = Buggy::getmicrotime();   
        $res = $end - $Buggy[$module];   
        return $res;   
    }   
  
    /**  
     * Buggy::Track()  
     *  
     * @param $module  
     * @param $msg      additional message to display  
     * @return   
     **/   
    function Track($module, $msg = '') {   
       
        global $Buggy;   
       
        if (!isset($Buggy[$module])) {   
               
            Buggy::SetMicroTime($module);   
               
        } else {   
               
            $time = Buggy::GetExecutionTime($module);   
            echo "<script>console.info("[Buggy] - $module - $msg - Execution Time: $time ")</script>\n";   
        }   
    }   
} 

Usage of the class is simply by setting different $module names to every part that you would like to track. Let say :

Buggy::Track('User Agent detection');   
if (ereg('MSIE',$_SERVER['HTTP_USER_AGENT'])) {   
    $agent = 'MSIE';   
} else {   
    $agent = 'Mozilla';   
}   
Buggy::Track('User Agent detection',$agent);

And in Firebug you have this message in console:

I simply altered the page with some JavaScript, and from PHP you can enable disable debugging message. Now we can add more advanced features for example we can track PHP errors inside Firebug and here is a more complete example :

/**  
 * Buggy inside Firebug - Advanced  
 *   
 * @package GONX  
 * @author hatem <hatem at php dot net>  
 * @website http://phpmagazine.net  
 * @copyright Copyright (c) 2005-2007  
 * @version $Id: buggy.class.php,v 2.2 2007/02/10 04:10:12 hatem Exp $  
 * @access public  
 **/   
class buggy {   
  
    function _init(){   
        $old_error_handler = set_error_handler(array("buggy","ErrorHandler"));   
        define ("FATAL",E_USER_ERROR);   
        define ("WARNING",E_USER_WARNING);   
        define ("NOTICE",E_USER_NOTICE);   
        // configure reporting level   
        error_reporting (FATAL | WARNING | NOTICE);    
    }   
  
    /**  
     * Buggy::getmicrotime()  
     *   
     * @return   
     **/   
    function getmicrotime(){   
        $mtime = microtime();   
        $mtime = explode(" ",$mtime);   
        $mtime = $mtime[1] + $mtime[0];   
        return ($mtime);   
    }   
  
    /**  
     * Buggy::SetMicroTime()  
     *   
     * @param $module  
     * @return   
     **/   
    function SetMicroTime($module)   
    {   
        global $Buggy;   
        $Buggy[$module] = Buggy::getmicrotime();   
        return $Buggy[$module];   
    }   
       
    /**  
     * Buggy::GetExecutionTime()  
     *   
     * @param $module  
     * @return   
     **/   
    function GetExecutionTime($module)   
    {   
        global $Buggy;   
        $end = Buggy::getmicrotime();   
        $res = $end - $Buggy[$module];   
        return $res;   
    }   
  
    /**  
     * Buggy::Track()  
     *  
     * @param $module  
     * @param $msg      additional message to display  
     * @return   
     **/   
    function Track($module, $msg = '') {   
       
        global $Buggy;   
       
        if (!isset($Buggy[$module])) {   
               
            Buggy::SetMicroTime($module);   
               
        } else {   
               
            $duration = Buggy::GetExecutionTime($module);   
            Buggy::logMessage($module,'Notice',$msg,$duration);   
           
        }   
       
    }   
       
    /**  
     * Buggy::logMessage()  
     *   
     * @param string $module  
     * @param string $type  
     * @param string $message  
     * @param string $duration  
     * @return   
     **/   
    function logMessage($module = '', $type = '', $message = '', $duration = ''){   
        if ($module == 'PHPError') {   
           
            if ($type == 'WARNING') {   
                echo "<script>console.warn("[Buggy] - $module [$type] - $message")</script>\n";   
            } elseif ($type == 'Fatal') {   
                echo "<script>console.error("[Buggy] - $module [$type] - $message")</script>\n";   
            }else{   
                echo "<script>console.info("[Buggy] - $module [$type] - $message")</script>\n";   
            }   
                   
        } else {   
            echo "<script>console.info("[Buggy] - $module [$type] - $message - Execution Time: $duration ")</script>\n";   
        }   
    }   
       
    /**  
     * Buggy errors manager  
     *   
     * @param $errno  
     * @param $errstr  
     * @param $errfile  
     * @param $errline  
     * @return   
     **/   
    function ErrorHandler ($errno, $errstr, $errfile, $errline) {   
      switch ($errno) {   
        case FATAL:   
        Buggy::logMessage('PHPError', 'Fatal', "{$errno} : $errstr - Fatal error in line ".$errline." of file ".$errfile);   
        exit(1);   
        break;   
           
        case WARNING:   
            Buggy::logMessage('PHPError', 'WARNING', "{$errno} : $errstr - WARNING error in line ".$errline." of file ".$errfile);   
        break;   
           
        default:   
            Buggy::logMessage('PHPError', 'Notice', "{$errno} : $errstr - Notice error in line ".$errline." of file ".$errfile);   
        break;   
      }   
    }   
  
}   
  
Buggy::_init();   
Buggy::Track('User Agent detection');   
if (ereg('MSIE',$_SERVER['HTTP_USER_AGENT'])) {   
    $agent = 'MSIE';   
} else {   
    $agent = 'Mozilla';   
}   
Buggy::Track('User Agent detection',$agent);   
  
  
trigger_error("Error Message", WARNING);   
trigger_error("Just for info", NOTICE);   
trigger_error("This is fatal", FATAL);

And below a screenshot of how results looks like in Firebug :
 

How To, Firebug, PHP, Scripts, Debug