gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

Exporter.php (8795B)


      1 <?php
      2 /*
      3  * This file is part of the Exporter package.
      4  *
      5  * (c) Sebastian Bergmann <sebastian@phpunit.de>
      6  *
      7  * For the full copyright and license information, please view the LICENSE
      8  * file that was distributed with this source code.
      9  */
     10 
     11 namespace SebastianBergmann\Exporter;
     12 
     13 use SebastianBergmann\RecursionContext\Context;
     14 
     15 /**
     16  * A nifty utility for visualizing PHP variables.
     17  *
     18  * <code>
     19  * <?php
     20  * use SebastianBergmann\Exporter\Exporter;
     21  *
     22  * $exporter = new Exporter;
     23  * print $exporter->export(new Exception);
     24  * </code>
     25  */
     26 class Exporter
     27 {
     28     /**
     29      * Exports a value as a string
     30      *
     31      * The output of this method is similar to the output of print_r(), but
     32      * improved in various aspects:
     33      *
     34      *  - NULL is rendered as "null" (instead of "")
     35      *  - TRUE is rendered as "true" (instead of "1")
     36      *  - FALSE is rendered as "false" (instead of "")
     37      *  - Strings are always quoted with single quotes
     38      *  - Carriage returns and newlines are normalized to \n
     39      *  - Recursion and repeated rendering is treated properly
     40      *
     41      * @param  mixed  $value
     42      * @param  int    $indentation The indentation level of the 2nd+ line
     43      * @return string
     44      */
     45     public function export($value, $indentation = 0)
     46     {
     47         return $this->recursiveExport($value, $indentation);
     48     }
     49 
     50     /**
     51      * @param  mixed   $data
     52      * @param  Context $context
     53      * @return string
     54      */
     55     public function shortenedRecursiveExport(&$data, Context $context = null)
     56     {
     57         $result   = array();
     58         $exporter = new self();
     59 
     60         if (!$context) {
     61             $context = new Context;
     62         }
     63 
     64         $context->add($data);
     65 
     66         foreach ($data as $key => $value) {
     67             if (is_array($value)) {
     68                 if ($context->contains($data[$key]) !== false) {
     69                     $result[] = '*RECURSION*';
     70                 }
     71 
     72                 else {
     73                     $result[] = sprintf(
     74                         'array(%s)',
     75                         $this->shortenedRecursiveExport($data[$key], $context)
     76                     );
     77                 }
     78             }
     79 
     80             else {
     81                 $result[] = $exporter->shortenedExport($value);
     82             }
     83         }
     84 
     85         return implode(', ', $result);
     86     }
     87 
     88     /**
     89      * Exports a value into a single-line string
     90      *
     91      * The output of this method is similar to the output of
     92      * SebastianBergmann\Exporter\Exporter::export. This method guarantees
     93      * thought that the result contains now newlines.
     94      *
     95      * Newlines are replaced by the visible string '\n'. Contents of arrays
     96      * and objects (if any) are replaced by '...'.
     97      *
     98      * @param  mixed  $value
     99      * @return string
    100      * @see    SebastianBergmann\Exporter\Exporter::export
    101      */
    102     public function shortenedExport($value)
    103     {
    104         if (is_string($value)) {
    105             $string = $this->export($value);
    106 
    107             if (strlen($string) > 40) {
    108                 $string = substr($string, 0, 30) . '...' . substr($string, -7);
    109             }
    110 
    111             return str_replace("\n", '\n', $string);
    112         }
    113 
    114         if (is_object($value)) {
    115             return sprintf(
    116                 '%s Object (%s)',
    117                 get_class($value),
    118                 count($this->toArray($value)) > 0 ? '...' : ''
    119             );
    120         }
    121 
    122         if (is_array($value)) {
    123             return sprintf(
    124                 'Array (%s)',
    125                 count($value) > 0 ? '...' : ''
    126             );
    127         }
    128 
    129         return $this->export($value);
    130     }
    131 
    132     /**
    133      * Converts an object to an array containing all of its private, protected
    134      * and public properties.
    135      *
    136      * @param  mixed $value
    137      * @return array
    138      */
    139     public function toArray($value)
    140     {
    141         if (!is_object($value)) {
    142             return (array) $value;
    143         }
    144 
    145         $array = array();
    146 
    147         foreach ((array) $value as $key => $val) {
    148             // properties are transformed to keys in the following way:
    149             // private   $property => "\0Classname\0property"
    150             // protected $property => "\0*\0property"
    151             // public    $property => "property"
    152             if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) {
    153                 $key = $matches[1];
    154             }
    155 
    156             // See https://github.com/php/php-src/commit/5721132
    157             if ($key === "\0gcdata") {
    158                 continue;
    159             }
    160 
    161             $array[$key] = $val;
    162         }
    163 
    164         // Some internal classes like SplObjectStorage don't work with the
    165         // above (fast) mechanism nor with reflection in Zend.
    166         // Format the output similarly to print_r() in this case
    167         if ($value instanceof \SplObjectStorage) {
    168             // However, the fast method does work in HHVM, and exposes the
    169             // internal implementation. Hide it again.
    170             if (property_exists('\SplObjectStorage', '__storage')) {
    171                 unset($array['__storage']);
    172             } elseif (property_exists('\SplObjectStorage', 'storage')) {
    173                 unset($array['storage']);
    174             }
    175 
    176             if (property_exists('\SplObjectStorage', '__key')) {
    177                 unset($array['__key']);
    178             }
    179 
    180             foreach ($value as $key => $val) {
    181                 $array[spl_object_hash($val)] = array(
    182                     'obj' => $val,
    183                     'inf' => $value->getInfo(),
    184                 );
    185             }
    186         }
    187 
    188         return $array;
    189     }
    190 
    191     /**
    192      * Recursive implementation of export
    193      *
    194      * @param  mixed                                       $value       The value to export
    195      * @param  int                                         $indentation The indentation level of the 2nd+ line
    196      * @param  \SebastianBergmann\RecursionContext\Context $processed   Previously processed objects
    197      * @return string
    198      * @see    SebastianBergmann\Exporter\Exporter::export
    199      */
    200     protected function recursiveExport(&$value, $indentation, $processed = null)
    201     {
    202         if ($value === null) {
    203             return 'null';
    204         }
    205 
    206         if ($value === true) {
    207             return 'true';
    208         }
    209 
    210         if ($value === false) {
    211             return 'false';
    212         }
    213 
    214         if (is_float($value) && floatval(intval($value)) === $value) {
    215             return "$value.0";
    216         }
    217 
    218         if (is_resource($value)) {
    219             return sprintf(
    220                 'resource(%d) of type (%s)',
    221                 $value,
    222                 get_resource_type($value)
    223             );
    224         }
    225 
    226         if (is_string($value)) {
    227             // Match for most non printable chars somewhat taking multibyte chars into account
    228             if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) {
    229                 return 'Binary String: 0x' . bin2hex($value);
    230             }
    231 
    232             return "'" .
    233             str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) .
    234             "'";
    235         }
    236 
    237         $whitespace = str_repeat(' ', 4 * $indentation);
    238 
    239         if (!$processed) {
    240             $processed = new Context;
    241         }
    242 
    243         if (is_array($value)) {
    244             if (($key = $processed->contains($value)) !== false) {
    245                 return 'Array &' . $key;
    246             }
    247 
    248             $key    = $processed->add($value);
    249             $values = '';
    250 
    251             if (count($value) > 0) {
    252                 foreach ($value as $k => $v) {
    253                     $values .= sprintf(
    254                         '%s    %s => %s' . "\n",
    255                         $whitespace,
    256                         $this->recursiveExport($k, $indentation),
    257                         $this->recursiveExport($value[$k], $indentation + 1, $processed)
    258                     );
    259                 }
    260 
    261                 $values = "\n" . $values . $whitespace;
    262             }
    263 
    264             return sprintf('Array &%s (%s)', $key, $values);
    265         }
    266 
    267         if (is_object($value)) {
    268             $class = get_class($value);
    269 
    270             if ($hash = $processed->contains($value)) {
    271                 return sprintf('%s Object &%s', $class, $hash);
    272             }
    273 
    274             $hash   = $processed->add($value);
    275             $values = '';
    276             $array  = $this->toArray($value);
    277 
    278             if (count($array) > 0) {
    279                 foreach ($array as $k => $v) {
    280                     $values .= sprintf(
    281                         '%s    %s => %s' . "\n",
    282                         $whitespace,
    283                         $this->recursiveExport($k, $indentation),
    284                         $this->recursiveExport($v, $indentation + 1, $processed)
    285                     );
    286                 }
    287 
    288                 $values = "\n" . $values . $whitespace;
    289             }
    290 
    291             return sprintf('%s Object &%s (%s)', $class, $hash, $values);
    292         }
    293 
    294         return var_export($value, true);
    295     }
    296 }