Open-Source PHP Framework - Designed for rapid development of performance-oriented scalable applications
1
<?php
/**
 * Valid output methods are: auto, FirePHP, html and text
 * The auto mode will select FirePHP if it is available, otherwise it will use html
 * Using FirePHP requires FireBug with the FirePHP extension enabled in FireFox (instructions at firephp.org)
 */
define('DEBUG_OUTPUT_METHOD', 'auto');

/**
 * Powers the debug system
 */
class debug {
    /**
     * Internal buffer exposing data between methods
     * @var float $_timeStart
     * @var string $_mode, $_modeStatic
     */
    protected $_timeStart, $_mode;
    protected static $_modeStatic;

    /**
     * Time storage for the timer
     * @var array
     */
    public static $timer = array();

    /**
     * Internal buffer to store SQL queries and log messages
     * @var array
     */
    private static $_queries = array(), $_log = array(), $_initTime = null;

    /**
     * Get the PHP microtime() relative to the start of the instance
     * @return float
     */
    public static function microtime() {
        $now = microtime(true);
        if (!self::$_initTime) {
            self::$_initTime = $now;
        }
        return ($now - self::$_initTime);
    }

    /**
     * Timer - sets breakpoints (aka. split times) and returns time since last breakpoint
     *
     * @param mixed $breakpointId Optional, any vector type is valid
     * @param mixed $id Optional, any vector type is valid
     * @return string Nicely formatted float
     */
    public static function timer($breakpointId = null, $id = 'default') {
        if (!isset(self::$timer[$id])) {
            $return = 0;
        }
        if (!$breakpointId) {
            self::$timer[$id][] = self::microtime();
        } else {
            self::$timer[$id][$breakpointId] = self::microtime();
        }
        if (!isset($return)) {
            $return = (end(self::$timer[$id]) - prev(self::$timer[$id]));
        }
        return number_format($return, 5);
    }

    /**
     * Return the total execution time for a timer - minimum of two breakpoints required for a non-zero return
     *
     * @param mixed $id Optional, any vector type is valid
     * @return string Nicely formatted float
     */
    public static function timerTotal($id = 'default') {
        $return = 0;
        if (isset(self::$timer[$id]) && count(self::$timer[$id]) > 1) {
            $return = (end(self::$timer[$id]) - reset(self::$timer[$id]));
        }
        return number_format($return, 5);
    }

    /**
     * Reports the total time table for a timer via the debug output mode
     *
     * @param mixed $id Optional, any vector type is valid
     * @return string Nicely formatted float
     */
    public static function timerReport($id = 'default') {
        if (!isset(self::$timer[$id])) {
            return null;
        }
        $last = reset(self::$timer[$id]);
        if (self::$_modeStatic == 'FirePHP') {
            $FirePHP = FirePHP::getInstance(true);
            foreach (self::$timer[$id] as $breakpointId => $val) {
                $FirePHP->info((string) $breakpointId, number_format(($val - $last), 5));
                $last = $val;
            }
        } else {
            foreach (self::$timer[$id] as $breakpointId => $val) {
                $return[] = number_format(($val - $last), 5) . ' - ' . $breakpointId;
                $last = $val;
            }
            if (self::$_modeStatic == 'html' || self::$_modeStatic == 'text') {
                $recordDelimiter = PHP_EOL . PHP_EOL;
                if (self::$_modeStatic == 'html') {
                    $recordDelimiter .= '<hr />';
                }
                echo $recordDelimiter . implode($recordDelimiter, $return) . $recordDelimiter;
            }
            return $return;
        }
    }

    /**
     * Logs a SQL query
     *
     * @param string $query
     * @param float $executionTime Optional
     * @param string $error Optional
     */
    public static function logQuery($query, $executionTime = null, $error = null) {
        self::$_queries[] = array('query' => $query, 'executionTime' => $executionTime, 'error' => $error);
    }

    /**
     * Logs a message
     *
     * @param str $data
     * @param str $type Valid options are log, info, warn and error
     */
    public static function log($data, $type = 'log') {
        self::$_log[] = array('data' => $data, 'method' => $type, 'time' => self::microtime());
    }

    /**
     * Initializes the debug system
     *
     * @param string $mode Optional. Mode of output by default is html, but the framework automatically overrides
     * this with your DEBUG_OUTPUT_METHOD setting
     */
    public function __construct($mode = 'html') {
        if ($mode == 'auto') {
            $mode = (strpos($_SERVER['HTTP_USER_AGENT'], 'FirePHP') !== false ? 'FirePHP'
                                                                              : (PHP_SAPI != 'cli' ? 'html' :
 
'text')); } if ($mode == 'FirePHP' && !class_exists('FirePHP')) { $configInit = new configInit; $firephpDir = $configInit->packagesPath() . 'FirePHPCore' . $configInit->DS; if (is_dir($firephpDir)) { require $firephpDir . 'FirePHP.class.php'; } if (!class_exists('FirePHP')) { $mode = 'html'; } } if ($mode == 'FirePHP' && ini_get('output_buffering') != 'On') { ob_start(); } self::$_modeStatic = $this->_mode = $mode; $this->_timeStart = self::microtime(); } /** * Tallies up the debug info and outputs it */ public function __destruct() { $execTime = 'Page execution time: ' . number_format(self::microtime() - $this->_timeStart, 5); $sqlExecString = 'Execution time of previous SQL: '; if ($this->_mode == 'FirePHP') { $FirePHP = FirePHP::getInstance(true); $FirePHP->info($execTime); if (!empty(self::$_log)) { $timeLast = $this->_timeStart; foreach (self::$_log as $logArray) { $data = '(' . number_format($logArray['time'] - $timeLast, 5) . ') ' . $logArray['data']; $FirePHP->{$logArray['method']}($data); $timeLast = $logArray['time']; } } if (!empty(self::$_queries)) { foreach (self::$_queries as $queryArray) { $FirePHP->group('SQL'); $FirePHP->log($queryArray['query']); if ($queryArray['executionTime'] !== null) { $FirePHP->info($sqlExecString . $queryArray['executionTime']); } if ($queryArray['error'] !== null) { $FirePHP->error($queryArray['error']); } $FirePHP->groupEnd(); } } } else { $recordDelimiter = PHP_EOL . PHP_EOL; $lineDelimiter = PHP_EOL; if ($this->_mode == 'html') { echo '<br style="clear: both;" />'; $recordDelimiter .= '<hr />'; $lineDelimiter .= '<br />'; } echo $recordDelimiter . $execTime; if (!empty(self::$_log)) { $timeLast = $this->_timeStart; foreach (self::$_log as $logArray) { echo $lineDelimiter . $logArray['method'] . ' (' . number_format($logArray['time'] - $timeLast, 5) . ') ' . get::htmlentities($logArray['data']); $timeLast = $logArray['time']; } } if (!empty(self::$_queries)) { foreach (self::$_queries as $queryArray) { echo $recordDelimiter . ($this->_mode == 'html' ? get::htmlentities($queryArray['query']) : $queryArray['query']); if ($queryArray['executionTime'] !== null) { echo $lineDelimiter . $sqlExecString . $queryArray['executionTime']; } if ($queryArray['error'] !== null) { echo $lineDelimiter . $queryArray['error']; } } } } } } $debugObject = new debug(DEBUG_OUTPUT_METHOD);