1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Koch Framework |
5
|
|
|
* Jens-André Koch © 2005 - onwards. |
6
|
|
|
* |
7
|
|
|
* This file is part of "Koch Framework". |
8
|
|
|
* |
9
|
|
|
* License: GNU/GPL v2 or any later version, see LICENSE file. |
10
|
|
|
* |
11
|
|
|
* This program is free software; you can redistribute it and/or modify |
12
|
|
|
* it under the terms of the GNU General Public License as published by |
13
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
14
|
|
|
* (at your option) any later version. |
15
|
|
|
* |
16
|
|
|
* This program is distributed in the hope that it will be useful, |
17
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19
|
|
|
* GNU General Public License for more details. |
20
|
|
|
* |
21
|
|
|
* You should have received a copy of the GNU General Public License |
22
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
23
|
|
|
*/ |
24
|
|
|
|
25
|
|
|
namespace Koch\Debug; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Debug. |
29
|
|
|
* |
30
|
|
|
* This class initializes debugging helpers like xdebug, the doctrine profiler, |
31
|
|
|
* firebug and printR at system start-up and displays debug |
32
|
|
|
* and runtime-informations on demand or at application shutdown. |
33
|
|
|
*/ |
34
|
|
|
class Debug |
|
|
|
|
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* This is an enhanced version of the native php function print_r(). |
38
|
|
|
* |
39
|
|
|
* @param mixed/array/object $var Array or Object as Variable to display |
|
|
|
|
40
|
|
|
* @returns Returns a better structured display of an array/object as native print_r(). |
41
|
|
|
*/ |
42
|
|
|
public static function printR($var) |
43
|
|
|
{ |
44
|
|
|
// this will handle more than one parameter |
45
|
|
|
if (func_num_args() > 1) { |
46
|
|
|
$vars = func_get_args(); |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
$backtrace_array = []; |
|
|
|
|
50
|
|
|
$backtrace_array = debug_backtrace(); |
|
|
|
|
51
|
|
|
$trace = array_shift($backtrace_array); |
|
|
|
|
52
|
|
|
$file = file($trace['file']); |
53
|
|
|
$trace_line = $file[$trace['line'] - 1]; |
|
|
|
|
54
|
|
|
|
55
|
|
|
echo '<pre>'; |
56
|
|
|
echo '<b>Debugging '; |
57
|
|
|
echo '<font color=red>' . basename($trace['file']) . '</font>'; |
58
|
|
|
echo ' on line <font color=red>' . $trace['line'] . '</font></b>:' . "\n"; |
59
|
|
|
echo "<div style='background: #f5f5f5; padding: 0.2em 0em;'>" . htmlspecialchars($trace_line) . '</div>' . "\n"; |
|
|
|
|
60
|
|
|
|
61
|
|
|
echo '<b>Type</b>: ' . gettype($var) . "\n"; // uhhh.. gettype is slow like hell |
62
|
|
|
|
63
|
|
|
// handle more than one parameter |
64
|
|
|
foreach ($vars as $var) { |
|
|
|
|
65
|
|
|
if (is_string($var)) { |
66
|
|
|
echo '<b>Length</b>: ' . strlen($var) . "\n"; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
if (is_array($var)) { |
70
|
|
|
echo '<b>Length</b>: ' . count($var) . "\n"; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
echo '<b>Value</b>: '; |
74
|
|
|
|
75
|
|
|
if ($var === true) { |
76
|
|
|
echo '<font color=green><b>true</b></font>'; |
77
|
|
|
} elseif ($var === false) { |
78
|
|
|
echo '<font color=red><b>false</b></font>'; |
79
|
|
|
} elseif ($var === null) { |
80
|
|
|
echo '<font color=red><b>null</b></font>'; |
81
|
|
|
} elseif ($var === 0) { |
82
|
|
|
echo '0'; |
83
|
|
|
} elseif (is_string($var) and strlen($var) === '0') { |
|
|
|
|
84
|
|
|
echo '<font color=green>*EMPTY STRING*</font>'; |
85
|
|
|
} elseif (is_string($var)) { |
86
|
|
|
echo htmlspecialchars($var); |
87
|
|
|
} else { |
88
|
|
|
$print_r = print_r($var, true); |
|
|
|
|
89
|
|
|
// str_contains < or > |
90
|
|
|
if ((strstr($print_r, '<') !== false) || (strstr($print_r, '>') !== false)) { |
|
|
|
|
91
|
|
|
$print_r = htmlspecialchars($print_r); |
|
|
|
|
92
|
|
|
} |
93
|
|
|
echo $print_r; |
|
|
|
|
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
echo '</pre>'; |
98
|
|
|
|
99
|
|
|
// save session before exit |
100
|
|
|
if ((bool) session_id()) { |
101
|
|
|
session_write_close(); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
// do not exit, if we are inside a test run |
105
|
|
|
if (defined('UNIT_TEST_RUN') === false or UNIT_TEST_RUN === false) { |
|
|
|
|
106
|
|
|
\Koch\Tools\ApplicationQuit::quit(); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Displays the content of a variable with var_dump. |
112
|
|
|
* The content gets escaping and pre tags are applied for better readability. |
113
|
|
|
* |
114
|
|
|
* @param mixed $var The variable to debug. |
115
|
|
|
* @param bool $exit Stop execution after dump? Default is true (stops). |
116
|
|
|
*/ |
117
|
|
|
public static function dump($var, $exit = true) |
118
|
|
|
{ |
119
|
|
|
// var_dump the content into a buffer and store it to variable |
120
|
|
|
ob_start(); |
121
|
|
|
var_dump($var); |
|
|
|
|
122
|
|
|
$var_dump = ob_get_clean(); |
|
|
|
|
123
|
|
|
|
124
|
|
|
/* |
125
|
|
|
* if xdebug is on and overloaded the var_dump function, |
126
|
|
|
* then the output is already properly escaped and prepared for direct output. |
127
|
|
|
* if xdebug is off, we need to apply escaping ourself. |
128
|
|
|
* html pre tags are applied to structure the display a bit more. |
129
|
|
|
*/ |
130
|
|
|
if (false === extension_loaded('xdebug')) { |
131
|
|
|
$var_dump = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $var_dump); |
|
|
|
|
132
|
|
|
$var_dump = '<pre>' . htmlspecialchars($var_dump, ENT_QUOTES, 'UTF-8') . '</pre>'; |
|
|
|
|
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
// display where this debug statement |
136
|
|
|
echo self::getOriginOfDebugCall(); |
137
|
|
|
|
138
|
|
|
// output the content of the buffer |
139
|
|
|
echo $var_dump; |
|
|
|
|
140
|
|
|
|
141
|
|
|
// do not exit, if we are inside a test run |
142
|
|
|
if (defined('UNIT_TEST_RUN') === false or UNIT_TEST_RUN === false) { |
|
|
|
|
143
|
|
|
if ($exit === true) { |
144
|
|
|
\Koch\Tools\ApplicationQuit::quit(); |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Debug logs the output of $var to the firebug console in your browser. |
151
|
|
|
* |
152
|
|
|
* @param mixed $var The variable to debug. |
153
|
|
|
* @param $logmethod The firebug method to call for logging (log,info,warn, error). Defaults to "log". |
154
|
|
|
* |
155
|
|
|
* @return FirePHP object. |
|
|
|
|
156
|
|
|
*/ |
157
|
|
|
public static function firebug($var, $logmethod = 'log') |
158
|
|
|
{ |
159
|
|
|
// @codeCoverageIgnoreStart |
160
|
|
|
// We don't need to test vendor library functionality. |
161
|
|
|
// @see FirePHPCore_FirePHPTest |
162
|
|
|
|
163
|
|
|
$firephp = \FirePHP::getInstance(true); |
164
|
|
|
|
165
|
|
|
/* |
166
|
|
|
* Adds an info message about the position of the firebug call (origin). |
167
|
|
|
* This is very helpful if you spread Debug::firebug() calls all over your code. |
168
|
|
|
*/ |
169
|
|
|
$firephp->info(self::getOriginOfDebugCall()); |
|
|
|
|
170
|
|
|
|
171
|
|
|
$firephp->{$logmethod}($var); |
172
|
|
|
|
173
|
|
|
// @codeCoverageIgnoreEnd |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Returns the position of a call. |
178
|
|
|
* |
179
|
|
|
* This is used to determine the origin of the debug call. |
180
|
|
|
* Its mostly used in combination with several debug calls, |
181
|
|
|
* like \Koch\Debug\Debug::firebug() or \Koch\Debug\Debug::printR() |
182
|
|
|
* which are enhanced debug displays. |
183
|
|
|
* |
184
|
|
|
* It is a very helpful reminder to find and remove debug calls, |
185
|
|
|
* which you spread all over your code while tracking down a bug, |
186
|
|
|
* but forgot the trace path or where exactly they are. |
187
|
|
|
* |
188
|
|
|
* If you have a multitude of debug calls, debug breadcrumbs or toc |
189
|
|
|
* would be good ;) But that's another story... |
190
|
|
|
* |
191
|
|
|
* The default level is 2 (0,1,2), because we have to skip |
192
|
|
|
* the 3 calls to dump() and getWhereDebugWasCalled(). |
193
|
|
|
* |
194
|
|
|
* @param int $level Default 1. |
195
|
|
|
* |
196
|
|
|
* @return string Message with origin of the debug call. |
|
|
|
|
197
|
|
|
*/ |
198
|
|
|
public static function getOriginOfDebugCall($level = 1) |
|
|
|
|
199
|
|
|
{ |
200
|
|
|
$trace = []; |
|
|
|
|
201
|
|
|
$file = $line = $function = $class = $object = $trace_line = ''; |
|
|
|
|
202
|
|
|
|
203
|
|
|
// Get the backtrace and the caller information. |
204
|
|
|
$trace = debug_backtrace(); |
205
|
|
|
$file = $trace[$level]['file']; |
206
|
|
|
$line = $trace[$level]['line']; |
207
|
|
|
#$function = $trace[$level]['function']; |
|
|
|
|
208
|
|
|
#$class = $trace[$level]['class']; |
|
|
|
|
209
|
|
|
|
210
|
|
|
/* |
211
|
|
|
* Get the file, to show the exact origin of the debug call. |
212
|
|
|
* The line with the call, is one line above. |
213
|
|
|
*/ |
214
|
|
|
$file_content = file($file); |
|
|
|
|
215
|
|
|
$origin_of_call = trim($file_content[ $trace[$level]['line'] - 1 ]); |
|
|
|
|
216
|
|
|
|
217
|
|
|
// do not use HTML tags on CLI |
218
|
|
|
if (PHP_SAPI === 'cli') { |
219
|
|
|
if (empty($_SERVER['REMOTE_ADDR'])) { |
220
|
|
|
$format = 'Debugging %s on line %s: %s' . "\n"; |
221
|
|
|
} else { |
222
|
|
|
$format = '<pre>'; |
223
|
|
|
$format .= '<b>Debugging <font color="red">%s</font> on line <font color="red">%s</font>:</b>' . "\n"; |
224
|
|
|
$format .= '<div style="background: #f5f5f5; padding: 0.2em 0em;">%s</div></pre>'; |
225
|
|
|
} |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
echo sprintf($format, basename($file), $line, htmlspecialchars($origin_of_call)); |
|
|
|
|
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* The method |
233
|
|
|
* - lists all currently included and required files |
234
|
|
|
* - counts all includes files |
235
|
|
|
* - calculates the total size (combined filesize) of all inclusions. |
236
|
|
|
*/ |
237
|
|
|
public static function getIncludedFiles($returnArray = false) |
238
|
|
|
{ |
239
|
|
|
// init vars |
240
|
|
|
$includedFiles = $files = $result = []; |
|
|
|
|
241
|
|
|
$totalSize = 0; |
242
|
|
|
|
243
|
|
|
// fetch all included files |
244
|
|
|
$files = get_included_files(); |
245
|
|
|
|
246
|
|
|
// loop over all included files and sum up filesize |
247
|
|
|
foreach ($files as $file) { |
248
|
|
|
|
249
|
|
|
// if system under test, skip virtual file system files, |
250
|
|
|
// as they might be already deleted by tearDown() methods. |
251
|
|
|
if (defined('UNIT_TEST_RUN') or UNIT_TEST_RUN) { |
|
|
|
|
252
|
|
|
if (stripos($file, 'vfs:/') !== false) { |
253
|
|
|
continue; |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
$size = filesize($file); |
258
|
|
|
$includedFiles[] = ['name' => $file, 'size' => $size]; |
259
|
|
|
$totalSize += $size; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$result = [ |
263
|
|
|
'count' => count($files), |
264
|
|
|
'size' => \Koch\Functions\Functions::getSize($totalSize), |
265
|
|
|
'files' => $includedFiles, |
266
|
|
|
]; |
267
|
|
|
|
268
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Lists all user defined constants (Application Constants). |
273
|
|
|
*/ |
274
|
|
|
public static function getApplicationConstants($returnArray = false) |
|
|
|
|
275
|
|
|
{ |
276
|
|
|
$constants = get_defined_constants(true); |
277
|
|
|
$result = $constants['user']; |
278
|
|
|
|
279
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
/** |
283
|
|
|
* Displayes the debug backtrace. |
284
|
|
|
* |
285
|
|
|
* @param int Limit the number of stack frames returned. Returns all stack frames by default (limit=0). |
286
|
|
|
* @param bool |
287
|
|
|
*/ |
288
|
|
|
public static function getBacktrace($limit = 0, $returnArray = false) |
289
|
|
|
{ |
290
|
|
|
$result = debug_backtrace($limit); |
291
|
|
|
|
292
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Returns an array with the name of the defined interfaces. |
297
|
|
|
*/ |
298
|
|
|
public static function getInterfaces($returnArray = false) |
299
|
|
|
{ |
300
|
|
|
$result = get_declared_interfaces(); |
301
|
|
|
|
302
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Returns an array with the name of the defined classes. |
307
|
|
|
*/ |
308
|
|
|
public static function getClasses($returnArray = false) |
309
|
|
|
{ |
310
|
|
|
$result = get_declared_classes(); |
311
|
|
|
|
312
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Returns an array with the name of the defined classes. |
317
|
|
|
*/ |
318
|
|
|
public static function getFunctions($returnArray = false) |
319
|
|
|
{ |
320
|
|
|
$result = get_defined_functions(); |
321
|
|
|
|
322
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* Lists all php extensions. |
327
|
|
|
*/ |
328
|
|
|
public static function getExtensions($returnArray = false) |
329
|
|
|
{ |
330
|
|
|
$result = get_loaded_extensions(); |
331
|
|
|
|
332
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* Lists all php.ini settings. |
337
|
|
|
*/ |
338
|
|
|
public static function getPhpIni($returnArray = false) |
339
|
|
|
{ |
340
|
|
|
$result = parse_ini_file(get_cfg_var('cfg_file_path'), true); |
341
|
|
|
|
342
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Lists all available wrappers. |
347
|
|
|
*/ |
348
|
|
|
public static function getWrappers($returnArray = false) |
349
|
|
|
{ |
350
|
|
|
$result = []; |
351
|
|
|
|
352
|
|
|
$wrappers = stream_get_wrappers(); |
353
|
|
|
|
354
|
|
|
$result['openssl'] = (extension_loaded('openssl')) ? 'yes' : 'no'; |
355
|
|
|
$result['http'] = in_array('http', $wrappers, true) ? 'yes' : 'no'; |
356
|
|
|
$result['https'] = in_array('https', $wrappers, true) ? 'yes' : 'no'; |
357
|
|
|
$result['all'] = $wrappers; |
358
|
|
|
|
359
|
|
|
return ($returnArray === true) ? $result : self::printR($result); |
360
|
|
|
} |
361
|
|
|
} |
362
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.