Вход Регистрация
Файл: vendor/sebastian/exporter/src/Exporter.php
Строк: 355
<?php declare(strict_types=1);
/*
 * This file is part of sebastian/exporter.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace SebastianBergmannExporter;

use function 
bin2hex;
use function 
count;
use function 
function_exists;
use function 
get_class;
use function 
get_resource_type;
use function 
gettype;
use function 
implode;
use function 
ini_get;
use function 
ini_set;
use function 
is_array;
use function 
is_float;
use function 
is_object;
use function 
is_resource;
use function 
is_string;
use function 
mb_strlen;
use function 
mb_substr;
use function 
preg_match;
use function 
spl_object_hash;
use function 
sprintf;
use function 
str_repeat;
use function 
str_replace;
use function 
strlen;
use function 
substr;
use function 
var_export;
use 
SebastianBergmannRecursionContextContext;
use 
SplObjectStorage;

/**
 * A nifty utility for visualizing PHP variables.
 *
 * <code>
 * <?php
 * use SebastianBergmannExporterExporter;
 *
 * $exporter = new Exporter;
 * print $exporter->export(new Exception);
 * </code>
 */
class Exporter
{
    
/**
     * Exports a value as a string.
     *
     * The output of this method is similar to the output of print_r(), but
     * improved in various aspects:
     *
     *  - NULL is rendered as "null" (instead of "")
     *  - TRUE is rendered as "true" (instead of "1")
     *  - FALSE is rendered as "false" (instead of "")
     *  - Strings are always quoted with single quotes
     *  - Carriage returns and newlines are normalized to n
     *  - Recursion and repeated rendering is treated properly
     *
     * @param int $indentation The indentation level of the 2nd+ line
     *
     * @return string
     */
    
public function export($value$indentation 0)
    {
        return 
$this->recursiveExport($value$indentation);
    }

    
/**
     * @param array<mixed> $data
     * @param Context      $context
     *
     * @return string
     */
    
public function shortenedRecursiveExport(&$dataContext $context null)
    {
        
$result   = [];
        
$exporter = new self();

        if (!
$context) {
            
$context = new Context;
        }

        
$array $data;
        
$context->add($data);

        foreach (
$array as $key => $value) {
            if (
is_array($value)) {
                if (
$context->contains($data[$key]) !== false) {
                    
$result[] = '*RECURSION*';
                } else {
                    
$result[] = sprintf(
                        
'array(%s)',
                        
$this->shortenedRecursiveExport($data[$key], $context)
                    );
                }
            } else {
                
$result[] = $exporter->shortenedExport($value);
            }
        }

        return 
implode(', '$result);
    }

    
/**
     * Exports a value into a single-line string.
     *
     * The output of this method is similar to the output of
     * SebastianBergmannExporterExporter::export().
     *
     * Newlines are replaced by the visible string 'n'.
     * Contents of arrays and objects (if any) are replaced by '...'.
     *
     * @return string
     *
     * @see    SebastianBergmannExporterExporter::export
     */
    
public function shortenedExport($value)
    {
        if (
is_string($value)) {
            
$string str_replace("n"''$this->export($value));

            if (
function_exists('mb_strlen')) {
                if (
mb_strlen($string) > 40) {
                    
$string mb_substr($string030) . '...' mb_substr($string, -7);
                }
            } else {
                if (
strlen($string) > 40) {
                    
$string substr($string030) . '...' substr($string, -7);
                }
            }

            return 
$string;
        }

        if (
is_object($value)) {
            return 
sprintf(
                
'%s Object (%s)',
                
get_class($value),
                
count($this->toArray($value)) > '...' ''
            
);
        }

        if (
is_array($value)) {
            return 
sprintf(
                
'Array (%s)',
                
count($value) > '...' ''
            
);
        }

        return 
$this->export($value);
    }

    
/**
     * Converts an object to an array containing all of its private, protected
     * and public properties.
     *
     * @return array
     */
    
public function toArray($value)
    {
        if (!
is_object($value)) {
            return (array) 
$value;
        }

        
$array = [];

        foreach ((array) 
$value as $key => $val) {
            
// Exception traces commonly reference hundreds to thousands of
            // objects currently loaded in memory. Including them in the result
            // has a severe negative performance impact.
            
if ("Errortrace" === $key || "Exceptiontrace" === $key) {
                continue;
            }

            
// properties are transformed to keys in the following way:
            // private   $property => "Classnameproperty"
            // protected $property => "*property"
            // public    $property => "property"
            
if (preg_match('/^.+(.+)$/', (string) $key$matches)) {
                
$key $matches[1];
            }

            
// See https://github.com/php/php-src/commit/5721132
            
if ($key === "gcdata") {
                continue;
            }

            
$array[$key] = $val;
        }

        
// Some internal classes like SplObjectStorage don't work with the
        // above (fast) mechanism nor with reflection in Zend.
        // Format the output similarly to print_r() in this case
        
if ($value instanceof SplObjectStorage) {
            foreach (
$value as $key => $val) {
                
$array[spl_object_hash($val)] = [
                    
'obj' => $val,
                    
'inf' => $value->getInfo(),
                ];
            }
        }

        return 
$array;
    }

    
/**
     * Recursive implementation of export.
     *
     * @param mixed                                       $value       The value to export
     * @param int                                         $indentation The indentation level of the 2nd+ line
     * @param SebastianBergmannRecursionContextContext $processed   Previously processed objects
     *
     * @return string
     *
     * @see    SebastianBergmannExporterExporter::export
     */
    
protected function recursiveExport(&$value$indentation$processed null)
    {
        if (
$value === null) {
            return 
'null';
        }

        if (
$value === true) {
            return 
'true';
        }

        if (
$value === false) {
            return 
'false';
        }

        if (
is_float($value)) {
            
$precisionBackup ini_get('precision');

            
ini_set('precision''-1');

            try {
                
$valueStr = (string) $value;

                if ((string) (int) 
$value === $valueStr) {
                    return 
$valueStr '.0';
                }

                return 
$valueStr;
            } finally {
                
ini_set('precision'$precisionBackup);
            }
        }

        if (
gettype($value) === 'resource (closed)') {
            return 
'resource (closed)';
        }

        if (
is_resource($value)) {
            return 
sprintf(
                
'resource(%d) of type (%s)',
                
$value,
                
get_resource_type($value)
            );
        }

        if (
is_string($value)) {
            
// Match for most non printable chars somewhat taking multibyte chars into account
            
if (preg_match('/[^x09-x0dx1bx20-xff]/'$value)) {
                return 
'Binary String: 0x' bin2hex($value);
            }

            return 
"'" .
            
str_replace(
                
'<lf>',
                
"n",
                
str_replace(
                    [
"rn""nr""r""n"],
                    [
'rn<lf>''nr<lf>''r<lf>''n<lf>'],
                    
$value
                
)
            ) .
            
"'";
        }

        
$whitespace str_repeat(' '$indentation);

        if (!
$processed) {
            
$processed = new Context;
        }

        if (
is_array($value)) {
            if ((
$key $processed->contains($value)) !== false) {
                return 
'Array &' $key;
            }

            
$array  $value;
            
$key    $processed->add($value);
            
$values '';

            if (
count($array) > 0) {
                foreach (
$array as $k => $v) {
                    
$values .= sprintf(
                        
'%s    %s => %s' "n",
                        
$whitespace,
                        
$this->recursiveExport($k$indentation),
                        
$this->recursiveExport($value[$k], $indentation 1$processed)
                    );
                }

                
$values "n" $values $whitespace;
            }

            return 
sprintf('Array &%s (%s)'$key$values);
        }

        if (
is_object($value)) {
            
$class get_class($value);

            if (
$hash $processed->contains($value)) {
                return 
sprintf('%s Object &%s'$class$hash);
            }

            
$hash   $processed->add($value);
            
$values '';
            
$array  $this->toArray($value);

            if (
count($array) > 0) {
                foreach (
$array as $k => $v) {
                    
$values .= sprintf(
                        
'%s    %s => %s' "n",
                        
$whitespace,
                        
$this->recursiveExport($k$indentation),
                        
$this->recursiveExport($v$indentation 1$processed)
                    );
                }

                
$values "n" $values $whitespace;
            }

            return 
sprintf('%s Object &%s (%s)'$class$hash$values);
        }

        return 
var_export($valuetrue);
    }
}
Онлайн: 1
Реклама