/.debug
[return to app]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($return, 5);
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($return, 5);
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) $breakpointId, number_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->_timeStart, 5);
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'] - $timeLast, 5) . ') ' . $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'] - $timeLast, 5) . ') '
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);