Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
// +----------------------------------------------------------------------+
4
// | PHP version 4                                                        |
5
// +----------------------------------------------------------------------+
6
// | Copyright (c) 1997-2006 The PHP Group                                |
7
// +----------------------------------------------------------------------+
8
// | This source file is subject to version 3.0 of the PHP license,       |
9
// | that is bundled with this package in the file LICENSE, and is        |
10
// | available through the world-wide-web at the following url:           |
11
// | http://www.php.net/license/3_0.txt.                                  |
12
// | If you did not receive a copy of the PHP license and are unable to   |
13
// | obtain it through the world-wide-web, please send a note to          |
14
// | license@php.net so we can mail you a copy immediately.               |
15
// +----------------------------------------------------------------------+
16
// | Authors: Frederic Poeydomenge <fpoeydomenge@free.fr>                 |
17
// +----------------------------------------------------------------------+
18
 
19
/**
20
 * Wrapper for the var_dump function.
21
 *
22
 * " The var_dump function displays structured information about expressions
23
 * that includes its type and value. Arrays are explored recursively
24
 * with values indented to show structure. "
25
 *
26
 * The Var_Dump class captures the output of the var_dump function,
27
 * by using output control functions, and then uses external renderer
28
 * classes for displaying the result in various graphical ways :
29
 * simple text, HTML/XHTML text, HTML/XHTML table, XML, ...
30
 *
31
 * @category  PHP
32
 * @package   Var_Dump
33
 * @author    Frederic Poeydomenge <fpoeydomenge@free.fr>
34
 * @copyright 1997-2006 The PHP Group
35
 * @license   http://www.php.net/license/3_0.txt PHP License 3.0
36
 * @version   CVS: $Id: Var_Dump.php 237750 2007-06-15 08:06:25Z fredericpoeydome $
37
 * @link      http://pear.php.net/package/Var_Dump
38
 */
39
 
40
/**
41
 * Include Renderer class
42
 */
43
 
44
require_once 'Var_Dump/Renderer.php';
45
 
46
/**
47
 * Constants
48
 */
49
 
50
define ('VAR_DUMP_START_GROUP',          1);
51
define ('VAR_DUMP_FINISH_GROUP',         2);
52
define ('VAR_DUMP_START_ELEMENT_NUM',    3);
53
define ('VAR_DUMP_START_ELEMENT_STR',    4);
54
define ('VAR_DUMP_FINISH_ELEMENT',       5);
55
define ('VAR_DUMP_FINISH_STRING',        6);
56
 
57
define ('VAR_DUMP_PREG_MATCH',           0);
58
define ('VAR_DUMP_PREG_SPACES',          1);
59
define ('VAR_DUMP_PREG_KEY_QUOTE',       2);
60
define ('VAR_DUMP_PREG_KEY',             3);
61
define ('VAR_DUMP_PREG_STRING_TYPE',     4);
62
define ('VAR_DUMP_PREG_STRING_LENGTH',   5);
63
define ('VAR_DUMP_PREG_STRING_VALUE',    6);
64
define ('VAR_DUMP_PREG_VALUE',           7);
65
define ('VAR_DUMP_PREG_VALUE_REFERENCE', 8);
66
define ('VAR_DUMP_PREG_VALUE_TYPE',      9);
67
define ('VAR_DUMP_PREG_VALUE_COMPL',    10);
68
define ('VAR_DUMP_PREG_VALUE_RESOURCE', 11);
69
define ('VAR_DUMP_PREG_ARRAY_END',      12);
70
define ('VAR_DUMP_PREG_ARRAY_START',    13);
71
define ('VAR_DUMP_PREG_ARRAY_TYPE',     14);
72
define ('VAR_DUMP_PREG_ARRAY_COUNT',    15);
73
define ('VAR_DUMP_PREG_STRING_COMPL',   16);
74
 
75
/**
76
 * Main class.
77
 *
78
 * @category  PHP
79
 * @package   Var_Dump
80
 * @author    Frederic Poeydomenge <fpoeydomenge@free.fr>
81
 * @copyright 1997-2006 The PHP Group
82
 * @license   http://www.php.net/license/3_0.txt PHP License 3.0
83
 * @version   CVS: $Id: Var_Dump.php 237750 2007-06-15 08:06:25Z fredericpoeydome $
84
 * @link      http://pear.php.net/package/Var_Dump
85
 */
86
 
87
class Var_Dump
88
{
89
 
90
    /**
91
     * Default configuration options.
92
     *
93
     * @var array
94
     * @access public
95
     */
96
    var $defaultOptions = array(
97
        'display_mode' => 'XHTML_Text', // Display mode.
98
        'ignore_list'  => NULL          // List of ignored class names.
99
    );
100
 
101
    /**
102
     * Run-time configuration options.
103
     *
104
     * @var array
105
     * @access public
106
     */
107
    var $options = array();
108
 
109
    /**
110
     * Rendering object.
111
     *
112
     * @var object
113
     * @access public
114
     */
115
    var $renderer = NULL;
116
 
117
    /**
118
     * Rendering configuration options.
119
     *
120
     * See Var_Dump/Renderer/*.php for the complete list of options
121
     *
122
     * @var array
123
     * @access public
124
     */
125
    var $rendererOptions = array();
126
 
127
    /**
128
     * Class constructor.
129
     *
130
     * The factory approach must be used in relationship with the
131
     * toString() method.
132
     * See Var_Dump/Renderer/*.php for the complete list of options
133
     *
134
     * @see Var_Dump::toString()
135
     * @param mixed $options String (display mode) or array (Global parameters).
136
     * @param array $rendererOptions Parameters for the rendering.
137
     * @access public
138
     */
139
    function Var_Dump($options = array(), $rendererOptions = array())
140
    {
141
 
142
        if (! is_null($options)) {
143
            if (is_string($options)) {
144
                $options = array(
145
                    'display_mode' => $options
146
                );
147
            }
148
            $this->options = array_merge (
149
                $this->defaultOptions,
150
                $options
151
            );
152
        }
153
 
154
        if (! is_null($rendererOptions) and is_array($rendererOptions)) {
155
            $this->rendererOptions = $rendererOptions;
156
            $this->renderer = & Var_Dump_Renderer::factory(
157
                $this->options['display_mode'],
158
                $this->rendererOptions
159
            );
160
        }
161
 
162
    }
163
 
164
    /**
165
     * Attempt to return a concrete Var_Dump instance.
166
     *
167
     * The factory approach must be used in relationship with the
168
     * toString() method.
169
     * See Var_Dump/Renderer/*.php for the complete list of options
170
     *
171
     * @see Var_Dump::toString()
172
     * @param mixed $options String (display mode) or array (Global parameters).
173
     * @param array $rendererOptions Parameters for the rendering.
174
     * @access public
175
     */
176
    function & factory($options = array(), $rendererOptions = array())
177
    {
178
        $obj = new Var_Dump($options, $rendererOptions);
179
        return $obj;
180
    }
181
 
182
    /**
183
     * Uses a renderer object to return the string representation of a variable.
184
     *
185
     * @param mixed $expression The variable to parse.
186
     * @return string The string representation of the variable.
187
     * @access public
188
     */
189
    function toString($expression)
190
    {
191
 
192
        if (is_null($this->renderer)) {
193
            return '';
194
        }
195
 
196
        $family = array(); // element family
197
        $depth  = array(); // element depth
198
        $type   = array(); // element type
199
        $value  = array(); // element value
200
 
201
        // When xdebug is loaded, disable the custom fancy var_dump() function,
202
        // that is not compatible with the regexp parsing below, by forcing
203
        // the "html_errors" configuration option to "off"
204
 
205
        if (extension_loaded('xdebug')) {
206
            ini_set('html_errors', '0');
207
        }
208
 
209
        // Captures the output of the var_dump function,
210
        // by using output control functions.
211
 
212
        ob_start();
213
        var_dump($expression);
214
        $variable = ob_get_contents();
215
        ob_end_clean();
216
 
217
        // When xdebug is loaded, restore the value of the
218
        // "html_errors" configuration option
219
 
220
        if (extension_loaded('xdebug')) {
221
            ini_restore('html_errors');
222
        }
223
 
224
        // Regexp that parses the output of the var_dump function.
225
        // The numbers between square brackets [] are the reference
226
        // of the captured subpattern, and correspond to the entries
227
        // in the resulting $matches array.
228
 
229
        preg_match_all(
230
            '!^
231
              (\s*)                                 # 2 spaces for each depth level
232
              (?:                                   #
233
                (?:\[("?)(.*?)\\2\]=>)              # Key [2-3]
234
                  |                                 #   or
235
                (?:(&?string\((\d+)\))\s+"(.*))     # String [4-6]
236
                  |                                 #   or
237
                (                                   # Value [7-11]
238
                  (&?)                              #   - reference [8]
239
                  (bool|int|float|resource|         #   - type [9]
240
                  NULL|\*RECURSION\*|UNKNOWN:0)     #
241
                  (?:\((.*?)\))?                    #   - complement [10]
242
                  (?:\sof\stype\s\((.*?)\))?        #   - resource [11]
243
                )                                   #
244
                  |                                 #   or
245
                (})                                 # End of array/object [12]
246
                  |                                 #   or
247
                (?:(&?(array|object)\((.+)\).*)\ {) # Start of array/object [13-15]
248
                  |                                 #   or
249
                (.*)                                # String (additional lines) [16]
250
              )                                     #
251
            $!Smx',
252
            $variable,
253
            $matches,
254
            PREG_SET_ORDER
255
        );
256
 
257
        // Used to keep the maxLen of the keys for each nested variable.
258
 
259
        $stackLen = array();
260
        $keyLen = array();
261
        $maxLen = 0;
262
 
263
        // Used when matching a string, to count the remaining
264
        // number of chars before the end of the string.
265
 
266
        $countdown = 0;
267
 
268
        // Loop through the matches of the previously defined regexp.
269
 
270
        reset($matches);
271
        while (list($key, $match) = each($matches)) {
272
 
273
            $count = count($match) - 1;
274
 
275
            // Find which alternative has been matched in the regexp,
276
            // by looking at the number of elements in the $match array.
277
 
278
            switch ($count) {
279
 
280
                // Key
281
                //=====
282
                // - Compute the maxLen of the keys at the actual depth
283
 
284
                case VAR_DUMP_PREG_KEY:
285
                    $len = strlen($match[VAR_DUMP_PREG_KEY]);
286
                    if ($len > $maxLen) {
287
                        $maxLen = $len;
288
                    }
289
                    if (empty($match[VAR_DUMP_PREG_KEY_QUOTE])) {
290
                        $family[] = VAR_DUMP_START_ELEMENT_NUM;
291
                    } else {
292
                        $family[] = VAR_DUMP_START_ELEMENT_STR;
293
                    }
294
                    $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
295
                    $type[]  = NULL;
296
                    $value[] = $match[VAR_DUMP_PREG_KEY];
297
                    break;
298
 
299
                // String
300
                //========
301
                // - Set the countdown (remaining number of chars before eol) =
302
                //   len of the string - matched len + 1 (final ")
303
 
304
                case VAR_DUMP_PREG_STRING_TYPE:
305
                case VAR_DUMP_PREG_STRING_LENGTH:
306
                case VAR_DUMP_PREG_STRING_VALUE:
307
                    $countdown =
308
                        $match[VAR_DUMP_PREG_STRING_LENGTH]
309
                        - strlen($match[VAR_DUMP_PREG_STRING_VALUE])
310
                        + 1;
311
                    $family[] = VAR_DUMP_FINISH_STRING;
312
                    $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
313
                    $type[] = $match[VAR_DUMP_PREG_STRING_TYPE];
314
                    if ($countdown == 0) {
315
                        $value[] = substr($match[VAR_DUMP_PREG_STRING_VALUE], 0, -1);
316
                    } else {
317
                        $value[] = $match[VAR_DUMP_PREG_STRING_VALUE];
318
                    }
319
                    break;
320
 
321
                // String (additional lines)
322
                //===========================
323
                // - Compute new countdown value
324
                // - Pop value off the end of the array, and concatenate new value
325
                // - Last additional line : remove trailing "
326
                // - Push new value onto the end of array
327
 
328
                case VAR_DUMP_PREG_STRING_COMPL:
329
                    if ($countdown > 0) {
330
                        $countdown -= strlen($match[VAR_DUMP_PREG_MATCH]) + 1;
331
                        $new_value =
332
                            array_pop($value) . "\n" .
333
                            $match[VAR_DUMP_PREG_STRING_COMPL];
334
                        if ($countdown == 0) {
335
                            $new_value = substr($new_value, 0, -1);
336
                        }
337
                        array_push($value, $new_value);
338
                    }
339
                    break;
340
 
341
                // Value
342
                //=======
343
 
344
                case VAR_DUMP_PREG_VALUE:
345
                case VAR_DUMP_PREG_VALUE_REFERENCE:
346
                case VAR_DUMP_PREG_VALUE_TYPE:
347
                case VAR_DUMP_PREG_VALUE_COMPL:
348
                case VAR_DUMP_PREG_VALUE_RESOURCE:
349
                    $family[] = VAR_DUMP_FINISH_ELEMENT;
350
                    $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
351
                    switch ($match[VAR_DUMP_PREG_VALUE_TYPE]) {
352
                        case 'bool':
353
                        case 'int':
354
                        case 'float':
355
                            $type[] =
356
                                $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
357
                                $match[VAR_DUMP_PREG_VALUE_TYPE];
358
                            $value[] = $match[VAR_DUMP_PREG_VALUE_COMPL];
359
                            break;
360
                        case 'resource':
361
                            $type[] =
362
                                $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
363
                                $match[VAR_DUMP_PREG_VALUE_TYPE] .
364
                                '(' . $match[VAR_DUMP_PREG_VALUE_RESOURCE] . ')';
365
                            $value[] = $match[VAR_DUMP_PREG_VALUE_COMPL];
366
                            break;
367
                        default:
368
                            $type[] =
369
                                $match[VAR_DUMP_PREG_VALUE_REFERENCE] .
370
                                $match[VAR_DUMP_PREG_VALUE_TYPE];
371
                            $value[] = NULL;
372
                            break;
373
                    }
374
                    break;
375
 
376
                // String (additional line containing a single "}")
377
                //==================================================
378
                // - see "case VAR_DUMP_PREG_STRING_COMPL" just above
379
                //
380
                // OR End of array/object
381
                //========================
382
                // - Pop the maxLen of the keys off the end of the stack
383
                // - If the last element on the stack is an array(0) or object(0),
384
                //   replace it by a standard element
385
 
386
                case VAR_DUMP_PREG_ARRAY_END:
387
 
388
                    if ($countdown > 0) {
389
                        // String
390
                        $countdown -= strlen($match[VAR_DUMP_PREG_MATCH]) + 1;
391
                        $new_value = array_pop($value) . "\n" . '}';
392
                        if ($countdown == 0) {
393
                            $new_value = substr($new_value, 0, -1);
394
                        }
395
                        array_push($value, $new_value);
396
                    } else {
397
                        // End of array/object
398
                        $oldLen = array_pop($stackLen);
399
                        $keyLen[$oldLen[0]] = $maxLen;
400
                        $maxLen = $oldLen[1];
401
                        if (
402
                            ($family[count($family) - 1] == VAR_DUMP_START_GROUP)
403
                                and
404
                            ($type[count($type) - 1] === 0)
405
                        ) {
406
                            $family[count($family) - 1] = VAR_DUMP_FINISH_ELEMENT;
407
                            $type[count($type) - 1] = $value[count($value) - 1];
408
                            $value[count($value) - 1] = NULL;
409
                        } else {
410
                            $family[] = VAR_DUMP_FINISH_GROUP;
411
                            $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
412
                            $type[] = NULL;
413
                            $value[] = $match[VAR_DUMP_PREG_ARRAY_END];
414
                        }
415
                    }
416
                    break;
417
 
418
                // Start of array/object
419
                //=======================
420
                // - If object is in the "ignore_list", jump at the end of it
421
                // - Else process it normally :
422
                //   - Push the maxLen of the keys onto the end of the stack
423
                //   - Initialize new maxLen to 0
424
 
425
                case VAR_DUMP_PREG_ARRAY_START:
426
                case VAR_DUMP_PREG_ARRAY_TYPE:
427
                case VAR_DUMP_PREG_ARRAY_COUNT:
428
 
429
                    $parse = TRUE;
430
 
431
                    // If object is in the "ignore_list", jump at the end of it.
432
 
433
                    if ($match[VAR_DUMP_PREG_ARRAY_TYPE] == 'object') {
434
                        $infos = $match[VAR_DUMP_PREG_ARRAY_COUNT];
435
                        $class_name = substr($infos, 0, strpos($infos, ')'));
436
                        if (
437
                            ! is_null($this->options['ignore_list'])
438
                                and
439
                            in_array($class_name, $this->options['ignore_list'])
440
                        ) {
441
                            $family[] = VAR_DUMP_FINISH_STRING;
442
                            $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
443
                            $type[] = 'object(' . $class_name . ')';
444
                            $value[] = 'Not parsed.';
445
                            while ($parse) {
446
                                list($dummy, $each) = each($matches);
447
                                if (
448
                                    $match[VAR_DUMP_PREG_SPACES] == $each[VAR_DUMP_PREG_SPACES]
449
                                        and
450
                                    (count($each) - 1) == VAR_DUMP_PREG_ARRAY_END
451
                                ) {
452
                                    $parse = FALSE;
453
                                }
454
                            };
455
                        }
456
                    }
457
 
458
                    // If not, process it normally.
459
 
460
                    if ($parse) {
461
 
462
                        array_push($stackLen, array(count($family), $maxLen));
463
                        $maxLen = 0;
464
                        $family[] = VAR_DUMP_START_GROUP;
465
                        $depth[] = strlen($match[VAR_DUMP_PREG_SPACES]) >> 1;
466
                        $type[] = (int) $match[VAR_DUMP_PREG_ARRAY_COUNT];
467
                        $value[] = $match[VAR_DUMP_PREG_ARRAY_START];
468
 
469
                    }
470
 
471
                    break;
472
 
473
            }
474
 
475
        }
476
 
477
        $this->renderer->initialize($family, $depth, $type, $value, $keyLen);
478
 
479
        return $this->renderer->toString();
480
 
481
    }
482
 
483
    /**
484
     * Attempt to return a concrete singleton Var_Dump instance.
485
     *
486
     * The singleton approach must be used in relationship with the
487
     * displayInit() and display() methods.
488
     * See Var_Dump/Renderer/*.php for the complete list of options
489
     *
490
     * @see Var_Dump::display(), Var_Dump::displayInit()
491
     * @return object Var_Dump instance
492
     * @access public
493
     */
494
    function & singleton()
495
    {
496
        static $instance;
497
        if (! isset($instance)) {
498
            $instance = new Var_Dump(array(), array(), array());
499
        }
500
        return $instance;
501
    }
502
 
503
    /**
504
     * Initialise the singleton object used by the display() method.
505
     *
506
     * @see Var_Dump::singleton(), Var_Dump::display()
507
     * @param mixed $options String (display mode) or array (Global parameters).
508
     * @param array $rendererOptions Parameters for the rendering.
509
     * @access public
510
     */
511
    function displayInit($options = array(), $rendererOptions = array())
512
    {
513
        $displayInit = & Var_Dump::singleton();
514
        $displayInit->Var_Dump($options, $rendererOptions);
515
    }
516
 
517
    /**
518
     * Outputs or returns a string representation of a variable.
519
     *
520
     * @see Var_Dump::singleton(), Var_Dump::displayInit()
521
     * @param mixed $expression The variable to parse.
522
     * @param bool $return Whether the variable should be echoed or returned.
523
     * @param mixed $options String (display mode) or array (Global parameters).
524
     * @param array $rendererOptions Parameters for the rendering.
525
     * @return string If returned, the string representation of the variable.
526
     * @access public
527
     */
528
    function display($expression, $return = FALSE, $options = NULL, $rendererOptions = NULL)
529
    {
530
        $display = & Var_Dump::singleton();
531
        if (! is_null($options) or ! is_null($rendererOptions)) {
532
            if (is_null($rendererOptions)) {
533
                $rendererOptions = array();
534
            }
535
            $display->Var_Dump($options, $rendererOptions);
536
        }
537
        if ($return === TRUE) {
538
            return $display->toString($expression);
539
        } else {
540
            echo $display->toString($expression);
541
        }
542
    }
543
 
544
}
545
 
546
?>