Open-Source PHP Framework - Designed for rapid development of performance-oriented scalable applications
1 <?php
2
/**
3  * Valid output methods are: auto, FirePHP, html and text
4  * The auto mode will select FirePHP if it is available, otherwise it will use html
5  * Using FirePHP requires FireBug with the FirePHP extension enabled in FireFox (instructions at firephp.org)
6  */
7
define('DEBUG_OUTPUT_METHOD''auto');
8
9
/**
10  * Powers the debug system
11  */
12
class debug {
13     
/**
14      * Internal buffer exposing data between methods
15      * @var float $_timeStart
16      * @var string $_mode, $_modeStatic
17      */
18     
protected $_timeStart$_mode;
19     protected static 
$_modeStatic;
20
21     
/**
22      * Time storage for the timer
23      * @var array
24      */
25     
public static $timer = array();
26
27     
/**
28      * Internal buffer to store SQL queries and log messages
29      * @var array
30      */
31     
private static $_queries = array(), $_log = array(), $_initTime null;
32
33     
/**
34      * Get the PHP microtime() relative to the start of the instance
35      * @return float
36      */
37     
public static function microtime() {
38         
$now microtime(true);
39         if (!
self::$_initTime) {
40             
self::$_initTime $now;
41         }
42         return (
$now self::$_initTime);
43     }
44
45     
/**
46      * Timer - sets breakpoints (aka. split times) and returns time since last breakpoint
47      *
48      * @param mixed $breakpointId Optional, any vector type is valid
49      * @param mixed $id Optional, any vector type is valid
50      * @return string Nicely formatted float
51      */
52     
public static function timer($breakpointId null$id 'default') {
53         if (!isset(
self::$timer[$id])) {
54             
$return 0;
55         }
56         if (!
$breakpointId) {
57             
self::$timer[$id][] = self::microtime();
58         } else {
59             
self::$timer[$id][$breakpointId] = self::microtime();
60         }
61         if (!isset(
$return)) {
62             
$return = (end(self::$timer[$id]) - prev(self::$timer[$id]));
63         }
64         return 
number_format($return5);
65     }
66
67     
/**
68      * Return the total execution time for a timer - minimum of two breakpoints required for a non-zero return
69      *
70      * @param mixed $id Optional, any vector type is valid
71      * @return string Nicely formatted float
72      */
73     
public static function timerTotal($id 'default') {
74         
$return 0;
75         if (isset(
self::$timer[$id]) && count(self::$timer[$id]) > 1) {
76             
$return = (end(self::$timer[$id]) - reset(self::$timer[$id]));
77         }
78         return 
number_format($return5);
79     }
80
81     
/**
82      * Reports the total time table for a timer via the debug output mode
83      *
84      * @param mixed $id Optional, any vector type is valid
85      * @return string Nicely formatted float
86      */
87     
public static function timerReport($id 'default') {
88         if (!isset(
self::$timer[$id])) {
89             return 
null;
90         }
91         
$last reset(self::$timer[$id]);
92         if (
self::$_modeStatic == 'FirePHP') {
93             
$FirePHP FirePHP::getInstance(true);
94             foreach (
self::$timer[$id] as $breakpointId => $val) {
95                 
$FirePHP->info((string) $breakpointIdnumber_format(($val $last), 5));
96                 
$last $val;
97             }
98         } else {
99             foreach (
self::$timer[$id] as $breakpointId => $val) {
100                 
$return[] = number_format(($val $last), 5) . ' - ' $breakpointId;
101                 
$last $val;
102             }
103             if (
self::$_modeStatic == 'html' || self::$_modeStatic == 'text') {
104                 
$recordDelimiter PHP_EOL PHP_EOL;
105                 if (
self::$_modeStatic == 'html') {
106                     
$recordDelimiter .= '<hr />';
107                 }
108                 echo 
$recordDelimiter implode($recordDelimiter$return) . $recordDelimiter;
109             }
110             return 
$return;
111         }
112     }
113
114     
/**
115      * Logs a SQL query
116      *
117      * @param string $query
118      * @param float $executionTime Optional
119      * @param string $error Optional
120      */
121     
public static function logQuery($query$executionTime null$error null) {
122         
self::$_queries[] = array('query' => $query'executionTime' => $executionTime'error' => $error);
123     }
124
125     
/**
126      * Logs a message
127      *
128      * @param str $data
129      * @param str $type Valid options are log, info, warn and error
130      */
131     
public static function log($data$type 'log') {
132         
self::$_log[] = array('data' => $data'method' => $type'time' => self::microtime());
133     }
134
135     
/**
136      * Initializes the debug system
137      *
138      * @param string $mode Optional. Mode of output by default is html, but the framework automatically overrides
139      * this with your DEBUG_OUTPUT_METHOD setting
140      */
141     
public function __construct($mode 'html') {
142         if (
$mode == 'auto') {
143             
$mode = (strpos($_SERVER['HTTP_USER_AGENT'], 'FirePHP') !== false 'FirePHP'
144                                                                               
: (PHP_SAPI != 'cli' 'html' :
 
'text'));
145         }
146         if (
$mode == 'FirePHP' && !class_exists('FirePHP')) {
147             
$configInit = new configInit;
148             
$firephpDir $configInit->packagesPath() . 'FirePHPCore' $configInit->DS;
149             if (
is_dir($firephpDir)) {
150                 require 
$firephpDir 'FirePHP.class.php';
151             }
152             if (!
class_exists('FirePHP')) {
153                 
$mode 'html';
154             }
155         }
156         if (
$mode == 'FirePHP' && ini_get('output_buffering') != 'On') {
157             
ob_start();
158         }
159         
self::$_modeStatic $this->_mode $mode;
160         
$this->_timeStart self::microtime();
161     }
162
163     
/**
164      * Tallies up the debug info and outputs it
165      */
166     
public function __destruct() {
167         
$execTime 'Page execution time: ' number_format(self::microtime() - $this->_timeStart5);
168         
$sqlExecString 'Execution time of previous SQL: ';
169         if (
$this->_mode == 'FirePHP') {
170             
$FirePHP FirePHP::getInstance(true);
171             
$FirePHP->info($execTime);
172             if (!empty(
self::$_log)) {
173                 
$timeLast $this->_timeStart;
174                 foreach (
self::$_log as $logArray) {
175                     
$data '(' number_format($logArray['time'] - $timeLast5) . ') ' $logArray['data'];
176                     
$FirePHP->{$logArray['method']}($data);
177                     
$timeLast $logArray['time'];
178                 }
179             }
180             if (!empty(
self::$_queries)) {
181                 foreach (
self::$_queries as $queryArray) {
182                     
$FirePHP->group('SQL');
183                     
$FirePHP->log($queryArray['query']);
184                     if (
$queryArray['executionTime'] !== null) {
185                         
$FirePHP->info($sqlExecString $queryArray['executionTime']);
186                     }
187                     if (
$queryArray['error'] !== null) {
188                         
$FirePHP->error($queryArray['error']);
189                     }
190                     
$FirePHP->groupEnd();
191                 }
192             }
193         } else {
194             
$recordDelimiter PHP_EOL PHP_EOL;
195             
$lineDelimiter PHP_EOL;
196             if (
$this->_mode == 'html') {
197                 echo 
'<br style="clear: both;" />';
198                 
$recordDelimiter .= '<hr />';
199                 
$lineDelimiter .= '<br />';
200             }
201             echo 
$recordDelimiter $execTime;
202             if (!empty(
self::$_log)) {
203                 
$timeLast $this->_timeStart;
204                 foreach (
self::$_log as $logArray) {
205                     echo 
$lineDelimiter $logArray['method']
206                        . 
' (' number_format($logArray['time'] - $timeLast5) . ') '
207                        
get::htmlentities($logArray['data']);
208                     
$timeLast $logArray['time'];
209                 }
210             }
211             if (!empty(
self::$_queries)) {
212                 foreach (
self::$_queries as $queryArray) {
213                     echo 
$recordDelimiter . ($this->_mode == 'html' get::htmlentities($queryArray['query'])
214                                                                     : 
$queryArray['query']);
215                     if (
$queryArray['executionTime'] !== null) {
216                         echo 
$lineDelimiter $sqlExecString $queryArray['executionTime'];
217                     }
218                     if (
$queryArray['error'] !== null) {
219                         echo 
$lineDelimiter $queryArray['error'];
220                     }
221                 }
222             }
223         }
224     }
225 }
226
$debugObject = new debug(DEBUG_OUTPUT_METHOD);