vendor/symfony/var-dumper/Dumper/AbstractDumper.php line 45

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\VarDumper\Dumper;
  11. use Symfony\Component\VarDumper\Cloner\Data;
  12. use Symfony\Component\VarDumper\Cloner\DumperInterface;
  13. /**
  14.  * Abstract mechanism for dumping a Data object.
  15.  *
  16.  * @author Nicolas Grekas <p@tchwork.com>
  17.  */
  18. abstract class AbstractDumper implements DataDumperInterfaceDumperInterface
  19. {
  20.     public const DUMP_LIGHT_ARRAY 1;
  21.     public const DUMP_STRING_LENGTH 2;
  22.     public const DUMP_COMMA_SEPARATOR 4;
  23.     public const DUMP_TRAILING_COMMA 8;
  24.     public static $defaultOutput 'php://output';
  25.     protected $line '';
  26.     protected $lineDumper;
  27.     protected $outputStream;
  28.     protected $decimalPoint '.';
  29.     protected $indentPad '  ';
  30.     protected $flags;
  31.     private string $charset '';
  32.     /**
  33.      * @param callable|resource|string|null $output  A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput
  34.      * @param string|null                   $charset The default character encoding to use for non-UTF8 strings
  35.      * @param int                           $flags   A bit field of static::DUMP_* constants to fine tune dumps representation
  36.      */
  37.     public function __construct($output nullstring $charset nullint $flags 0)
  38.     {
  39.         $this->flags $flags;
  40.         $this->setCharset($charset ?: \ini_get('php.output_encoding') ?: \ini_get('default_charset') ?: 'UTF-8');
  41.         $this->setOutput($output ?: static::$defaultOutput);
  42.         if (!$output && \is_string(static::$defaultOutput)) {
  43.             static::$defaultOutput $this->outputStream;
  44.         }
  45.     }
  46.     /**
  47.      * Sets the output destination of the dumps.
  48.      *
  49.      * @param callable|resource|string $output A line dumper callable, an opened stream or an output path
  50.      *
  51.      * @return callable|resource|string The previous output destination
  52.      */
  53.     public function setOutput($output)
  54.     {
  55.         $prev $this->outputStream ?? $this->lineDumper;
  56.         if (\is_callable($output)) {
  57.             $this->outputStream null;
  58.             $this->lineDumper $output;
  59.         } else {
  60.             if (\is_string($output)) {
  61.                 $output fopen($output'w');
  62.             }
  63.             $this->outputStream $output;
  64.             $this->lineDumper $this->echoLine(...);
  65.         }
  66.         return $prev;
  67.     }
  68.     /**
  69.      * Sets the default character encoding to use for non-UTF8 strings.
  70.      *
  71.      * @return string The previous charset
  72.      */
  73.     public function setCharset(string $charset): string
  74.     {
  75.         $prev $this->charset;
  76.         $charset strtoupper($charset);
  77.         $charset null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset 'CP1252' $charset;
  78.         $this->charset $charset;
  79.         return $prev;
  80.     }
  81.     /**
  82.      * Sets the indentation pad string.
  83.      *
  84.      * @param string $pad A string that will be prepended to dumped lines, repeated by nesting level
  85.      *
  86.      * @return string The previous indent pad
  87.      */
  88.     public function setIndentPad(string $pad): string
  89.     {
  90.         $prev $this->indentPad;
  91.         $this->indentPad $pad;
  92.         return $prev;
  93.     }
  94.     /**
  95.      * Dumps a Data object.
  96.      *
  97.      * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump
  98.      *
  99.      * @return string|null The dump as string when $output is true
  100.      */
  101.     public function dump(Data $data$output null): ?string
  102.     {
  103.         if ($locale $this->flags & (self::DUMP_COMMA_SEPARATOR self::DUMP_TRAILING_COMMA) ? setlocale(\LC_NUMERIC0) : null) {
  104.             setlocale(\LC_NUMERIC'C');
  105.         }
  106.         if ($returnDump true === $output) {
  107.             $output fopen('php://memory''r+');
  108.         }
  109.         if ($output) {
  110.             $prevOutput $this->setOutput($output);
  111.         }
  112.         try {
  113.             $data->dump($this);
  114.             $this->dumpLine(-1);
  115.             if ($returnDump) {
  116.                 $result stream_get_contents($output, -10);
  117.                 fclose($output);
  118.                 return $result;
  119.             }
  120.         } finally {
  121.             if ($output) {
  122.                 $this->setOutput($prevOutput);
  123.             }
  124.             if ($locale) {
  125.                 setlocale(\LC_NUMERIC$locale);
  126.             }
  127.         }
  128.         return null;
  129.     }
  130.     /**
  131.      * Dumps the current line.
  132.      *
  133.      * @param int $depth The recursive depth in the dumped structure for the line being dumped,
  134.      *                   or -1 to signal the end-of-dump to the line dumper callable
  135.      */
  136.     protected function dumpLine(int $depth)
  137.     {
  138.         ($this->lineDumper)($this->line$depth$this->indentPad);
  139.         $this->line '';
  140.     }
  141.     /**
  142.      * Generic line dumper callback.
  143.      */
  144.     protected function echoLine(string $lineint $depthstring $indentPad)
  145.     {
  146.         if (-!== $depth) {
  147.             fwrite($this->outputStreamstr_repeat($indentPad$depth).$line."\n");
  148.         }
  149.     }
  150.     /**
  151.      * Converts a non-UTF-8 string to UTF-8.
  152.      */
  153.     protected function utf8Encode(?string $s): ?string
  154.     {
  155.         if (null === $s || preg_match('//u'$s)) {
  156.             return $s;
  157.         }
  158.         if (!\function_exists('iconv')) {
  159.             throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.');
  160.         }
  161.         if (false !== $c = @iconv($this->charset'UTF-8'$s)) {
  162.             return $c;
  163.         }
  164.         if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252''UTF-8'$s)) {
  165.             return $c;
  166.         }
  167.         return iconv('CP850''UTF-8'$s);
  168.     }
  169. }