[Web] Update composer libs

- Removing symfony/deprecation-contracts (v2.4.0)
  - Upgrading ddeboer/imap (1.12.1 => 1.13.1)
  - Upgrading directorytree/ldaprecord (v2.6.3 => v2.10.1)
  - Upgrading illuminate/contracts (v8.53.1 => v9.3.0)
  - Upgrading nesbot/carbon (2.51.1 => 2.57.0)
  - Upgrading phpmailer/phpmailer (v6.5.0 => v6.6.0)
  - Upgrading psr/container (1.1.1 => 2.0.2)
  - Upgrading psr/log (1.1.4 => 3.0.0)
  - Upgrading psr/simple-cache (1.0.1 => 2.0.0)
  - Upgrading robthree/twofactorauth (1.8.0 => 1.8.1)
  - Upgrading symfony/polyfill-ctype (v1.23.0 => v1.24.0)
  - Upgrading symfony/polyfill-mbstring (v1.23.1 => v1.24.0)
  - Upgrading symfony/polyfill-php80 (v1.23.1 => v1.24.0)
  - Upgrading symfony/translation (v5.3.4 => v6.0.5)
  - Upgrading symfony/translation-contracts (v2.4.0 => v3.0.0)
  - Upgrading symfony/var-dumper (v5.3.6 => v6.0.5)
  - Upgrading tightenco/collect (v8.34.0 => v8.83.2)
  - Upgrading twig/twig (v3.3.2 => v3.3.8)
This commit is contained in:
andryyy
2022-03-02 20:08:24 +01:00
parent 24275ffdbf
commit 98bc947d00
940 changed files with 7649 additions and 14226 deletions

View File

@@ -1,6 +1,13 @@
CHANGELOG
=========
5.4
---
* Add ability to style integer and double values independently
* Add casters for Symfony's UUIDs and ULIDs
* Add support for `Fiber`
5.2.0
-----

View File

@@ -20,7 +20,7 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class ArgsStub extends EnumStub
{
private static $parameters = [];
private static array $parameters = [];
public function __construct(array $args, string $function, ?string $class)
{

View File

@@ -41,8 +41,6 @@ class Caster
* Casts objects to arrays and adds the dynamic property prefix.
*
* @param bool $hasDebugInfo Whether the __debugInfo method exists on $obj or not
*
* @return array The array-cast of the object, with prefixed dynamic properties
*/
public static function castObject(object $obj, string $class, bool $hasDebugInfo = false, string $debugClass = null): array
{
@@ -118,8 +116,6 @@ class Caster
* @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out
* @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set
* @param int &$count Set to the number of removed properties
*
* @return array The filtered array
*/
public static function filter(array $a, int $filter, array $listedProperties = [], ?int &$count = 0): array
{

View File

@@ -24,7 +24,7 @@ class ClassStub extends ConstStub
* @param string $identifier A PHP identifier, e.g. a class, method, interface, etc. name
* @param callable $callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier
*/
public function __construct(string $identifier, $callable = null)
public function __construct(string $identifier, callable|array|string $callable = null)
{
$this->value = $identifier;
@@ -87,7 +87,7 @@ class ClassStub extends ConstStub
}
}
public static function wrapCallable($callable)
public static function wrapCallable(mixed $callable)
{
if (\is_object($callable) || !\is_callable($callable)) {
return $callable;

View File

@@ -20,16 +20,13 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class ConstStub extends Stub
{
public function __construct(string $name, $value = null)
public function __construct(string $name, string|int|float $value = null)
{
$this->class = $name;
$this->value = 1 < \func_num_args() ? $value : $name;
}
/**
* @return string
*/
public function __toString()
public function __toString(): string
{
return (string) $this->value;
}

View File

@@ -20,7 +20,7 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class CutStub extends Stub
{
public function __construct($value)
public function __construct(mixed $value)
{
$this->value = $value;

View File

@@ -49,7 +49,7 @@ class DateCaster
public static function castInterval(\DateInterval $interval, array $a, Stub $stub, bool $isNested, int $filter)
{
$now = new \DateTimeImmutable();
$now = new \DateTimeImmutable('@0', new \DateTimeZone('UTC'));
$numberOfSeconds = $now->add($interval)->getTimestamp() - $now->getTimestamp();
$title = number_format($numberOfSeconds, 0, '.', ' ').'s';
@@ -63,7 +63,8 @@ class DateCaster
$format = '%R ';
if (0 === $i->y && 0 === $i->m && ($i->h >= 24 || $i->i >= 60 || $i->s >= 60)) {
$i = date_diff($d = new \DateTime(), date_add(clone $d, $i)); // recalculate carry over points
$d = new \DateTimeImmutable('@0', new \DateTimeZone('UTC'));
$i = $d->diff($d->add($i)); // recalculate carry over points
$format .= 0 < $i->days ? '%ad ' : '';
} else {
$format .= ($i->y ? '%yy ' : '').($i->m ? '%mm ' : '').($i->d ? '%dd ' : '');

View File

@@ -18,7 +18,7 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class DsPairStub extends Stub
{
public function __construct($key, $value)
public function __construct(string|int $key, mixed $value)
{
$this->value = [
Caster::PREFIX_VIRTUAL.'key' => $key,

View File

@@ -24,9 +24,9 @@ use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
*/
class ExceptionCaster
{
public static $srcContext = 1;
public static $traceArgs = true;
public static $errorTypes = [
public static int $srcContext = 1;
public static bool $traceArgs = true;
public static array $errorTypes = [
\E_DEPRECATED => 'E_DEPRECATED',
\E_USER_DEPRECATED => 'E_USER_DEPRECATED',
\E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
@@ -44,7 +44,7 @@ class ExceptionCaster
\E_STRICT => 'E_STRICT',
];
private static $framesCache = [];
private static array $framesCache = [];
public static function castError(\Error $e, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
@@ -214,18 +214,24 @@ class ExceptionCaster
if (is_file($f['file']) && 0 <= self::$srcContext) {
if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
$template = $f['object'] ?? unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
$ellipsis = 0;
$templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
$templateInfo = $template->getDebugInfo();
if (isset($templateInfo[$f['line']])) {
if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) {
$templatePath = null;
}
if ($templateSrc) {
$src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
$srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
$template = null;
if (isset($f['object'])) {
$template = $f['object'];
} elseif ((new \ReflectionClass($f['class']))->isInstantiable()) {
$template = unserialize(sprintf('O:%d:"%s":0:{}', \strlen($f['class']), $f['class']));
}
if (null !== $template) {
$ellipsis = 0;
$templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
$templateInfo = $template->getDebugInfo();
if (isset($templateInfo[$f['line']])) {
if (!method_exists($template, 'getSourceContext') || !is_file($templatePath = $template->getSourceContext()->getPath())) {
$templatePath = null;
}
if ($templateSrc) {
$src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, 'twig', $templatePath, $f);
$srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']];
}
}
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* Casts Fiber related classes to array representation.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
final class FiberCaster
{
public static function castFiber(\Fiber $fiber, array $a, Stub $stub, bool $isNested, int $filter = 0)
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($fiber->isTerminated()) {
$status = 'terminated';
} elseif ($fiber->isRunning()) {
$status = 'running';
} elseif ($fiber->isSuspended()) {
$status = 'suspended';
} elseif ($fiber->isStarted()) {
$status = 'started';
} else {
$status = 'not started';
}
$a[$prefix.'status'] = $status;
return $a;
}
}

View File

@@ -20,8 +20,8 @@ class LinkStub extends ConstStub
{
public $inVendor = false;
private static $vendorRoots;
private static $composerRoots;
private static array $vendorRoots;
private static array $composerRoots = [];
public function __construct(string $label, int $line = 0, string $href = null)
{
@@ -65,7 +65,7 @@ class LinkStub extends ConstStub
private function getComposerRoot(string $file, bool &$inVendor)
{
if (null === self::$vendorRoots) {
if (!isset(self::$vendorRoots)) {
self::$vendorRoots = [];
foreach (get_declared_classes() as $class) {

View File

@@ -20,8 +20,8 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class MemcachedCaster
{
private static $optionConstants;
private static $defaultOptions;
private static array $optionConstants;
private static array $defaultOptions;
public static function castMemcached(\Memcached $c, array $a, Stub $stub, bool $isNested)
{

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
final class MysqliCaster
{
public static function castMysqliDriver(\mysqli_driver $c, array $a, Stub $stub, bool $isNested): array
{
foreach ($a as $k => $v) {
if (isset($c->$k)) {
$a[$k] = $c->$k;
}
}
return $a;
}
}

View File

@@ -166,7 +166,7 @@ class RdKafkaCaster
return $a;
}
private static function extractMetadata($c)
private static function extractMetadata(KafkaConsumer|\RdKafka $c)
{
$prefix = Caster::PREFIX_VIRTUAL;

View File

@@ -102,10 +102,7 @@ class RedisCaster
return $a;
}
/**
* @param \Redis|\RedisArray|\RedisCluster $redis
*/
private static function getRedisOptions($redis, array $options = []): EnumStub
private static function getRedisOptions(\Redis|\RedisArray|\RedisCluster $redis, array $options = []): EnumStub
{
$serializer = $redis->getOption(\Redis::OPT_SERIALIZER);
if (\is_array($serializer)) {

View File

@@ -96,7 +96,7 @@ class ReflectionCaster
{
$prefix = Caster::PREFIX_VIRTUAL;
if ($c instanceof \ReflectionNamedType || \PHP_VERSION_ID < 80000) {
if ($c instanceof \ReflectionNamedType) {
$a += [
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
$prefix.'allowsNull' => $c->allowsNull(),
@@ -144,7 +144,7 @@ class ReflectionCaster
array_unshift($trace, [
'function' => 'yield',
'file' => $function->getExecutingFile(),
'line' => $function->getExecutingLine() - 1,
'line' => $function->getExecutingLine() - (int) (\PHP_VERSION_ID < 80100),
]);
$trace[] = $frame;
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
@@ -289,15 +289,17 @@ class ReflectionCaster
unset($a[$prefix.'allowsNull']);
}
try {
$a[$prefix.'default'] = $v = $c->getDefaultValue();
if ($c->isDefaultValueConstant()) {
$a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
if ($c->isOptional()) {
try {
$a[$prefix.'default'] = $v = $c->getDefaultValue();
if ($c->isDefaultValueConstant()) {
$a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
}
if (null === $v) {
unset($a[$prefix.'allowsNull']);
}
} catch (\ReflectionException $e) {
}
if (null === $v) {
unset($a[$prefix.'allowsNull']);
}
} catch (\ReflectionException $e) {
}
return $a;
@@ -384,6 +386,8 @@ class ReflectionCaster
$signature .= 10 > \strlen($v) && !str_contains($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
} elseif (\is_bool($v)) {
$signature .= $v ? 'true' : 'false';
} elseif (\is_object($v)) {
$signature .= 'new '.substr(strrchr('\\'.get_debug_type($v), '\\'), 1);
} else {
$signature .= $v;
}
@@ -417,7 +421,7 @@ class ReflectionCaster
private static function addMap(array &$a, object $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL)
{
foreach ($map as $k => $m) {
if (\PHP_VERSION_ID >= 80000 && 'isDisabled' === $k) {
if ('isDisabled' === $k) {
continue;
}
@@ -429,10 +433,8 @@ class ReflectionCaster
private static function addAttributes(array &$a, \Reflector $c, string $prefix = Caster::PREFIX_VIRTUAL): void
{
if (\PHP_VERSION_ID >= 80000) {
foreach ($c->getAttributes() as $n) {
$a[$prefix.'attributes'][] = $n;
}
foreach ($c->getAttributes() as $n) {
$a[$prefix.'attributes'][] = $n;
}
}
}

View File

@@ -22,12 +22,7 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class ResourceCaster
{
/**
* @param \CurlHandle|resource $h
*
* @return array
*/
public static function castCurl($h, array $a, Stub $stub, bool $isNested)
public static function castCurl(\CurlHandle $h, array $a, Stub $stub, bool $isNested): array
{
return curl_getinfo($h);
}

View File

@@ -94,32 +94,24 @@ class SplCaster
unset($a["\0SplFileInfo\0fileName"]);
unset($a["\0SplFileInfo\0pathName"]);
if (\PHP_VERSION_ID < 80000) {
if (false === $c->getPathname()) {
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
try {
$c->isReadable();
} catch (\RuntimeException $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
} else {
try {
$c->isReadable();
} catch (\RuntimeException $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
} catch (\Error $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
return $a;
} catch (\Error $e) {
if ('Object not initialized' !== $e->getMessage()) {
throw $e;
}
$a[$prefix.'⚠'] = 'The parent constructor was not called: the object is in an invalid state';
return $a;
}
foreach ($map as $key => $accessor) {
@@ -219,7 +211,7 @@ class SplCaster
return $a;
}
private static function castSplArray($c, array $a, Stub $stub, bool $isNested): array
private static function castSplArray(\ArrayObject|\ArrayIterator $c, array $a, Stub $stub, bool $isNested): array
{
$prefix = Caster::PREFIX_VIRTUAL;
$flags = $c->getFlags();
@@ -229,9 +221,6 @@ class SplCaster
$a = Caster::castObject($c, \get_class($c), method_exists($c, '__debugInfo'), $stub->class);
$c->setFlags($flags);
}
if (\PHP_VERSION_ID < 70400) {
$a[$prefix.'storage'] = $c->getArrayCopy();
}
$a += [
$prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST),
$prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS),

View File

@@ -12,6 +12,8 @@
namespace Symfony\Component\VarDumper\Caster;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\VarDumper\Cloner\Stub;
/**
@@ -66,4 +68,30 @@ class SymfonyCaster
return $a;
}
public static function castUuid(Uuid $uuid, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'toBase58'] = $uuid->toBase58();
$a[Caster::PREFIX_VIRTUAL.'toBase32'] = $uuid->toBase32();
// symfony/uid >= 5.3
if (method_exists($uuid, 'getDateTime')) {
$a[Caster::PREFIX_VIRTUAL.'time'] = $uuid->getDateTime()->format('Y-m-d H:i:s.u \U\T\C');
}
return $a;
}
public static function castUlid(Ulid $ulid, array $a, Stub $stub, bool $isNested)
{
$a[Caster::PREFIX_VIRTUAL.'toBase58'] = $ulid->toBase58();
$a[Caster::PREFIX_VIRTUAL.'toRfc4122'] = $ulid->toRfc4122();
// symfony/uid >= 5.3
if (method_exists($ulid, 'getDateTime')) {
$a[Caster::PREFIX_VIRTUAL.'time'] = $ulid->getDateTime()->format('Y-m-d H:i:s.v \U\T\C');
}
return $a;
}
}

View File

@@ -44,6 +44,22 @@ class XmlReaderCaster
public static function castXmlReader(\XMLReader $reader, array $a, Stub $stub, bool $isNested)
{
try {
$properties = [
'LOADDTD' => @$reader->getParserProperty(\XMLReader::LOADDTD),
'DEFAULTATTRS' => @$reader->getParserProperty(\XMLReader::DEFAULTATTRS),
'VALIDATE' => @$reader->getParserProperty(\XMLReader::VALIDATE),
'SUBST_ENTITIES' => @$reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
];
} catch (\Error $e) {
$properties = [
'LOADDTD' => false,
'DEFAULTATTRS' => false,
'VALIDATE' => false,
'SUBST_ENTITIES' => false,
];
}
$props = Caster::PREFIX_VIRTUAL.'parserProperties';
$info = [
'localName' => $reader->localName,
@@ -57,12 +73,7 @@ class XmlReaderCaster
'value' => $reader->value,
'namespaceURI' => $reader->namespaceURI,
'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI,
$props => [
'LOADDTD' => $reader->getParserProperty(\XMLReader::LOADDTD),
'DEFAULTATTRS' => $reader->getParserProperty(\XMLReader::DEFAULTATTRS),
'VALIDATE' => $reader->getParserProperty(\XMLReader::VALIDATE),
'SUBST_ENTITIES' => $reader->getParserProperty(\XMLReader::SUBST_ENTITIES),
],
$props => $properties,
];
if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, [], $count)) {

View File

@@ -29,6 +29,8 @@ abstract class AbstractCloner implements ClonerInterface
'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castStub'],
'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'castEnum'],
'Fiber' => ['Symfony\Component\VarDumper\Caster\FiberCaster', 'castFiber'],
'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'],
'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'],
'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'],
@@ -81,11 +83,15 @@ abstract class AbstractCloner implements ClonerInterface
'Symfony\Bridge\Monolog\Logger' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
'Symfony\Component\EventDispatcher\EventDispatcherInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster', 'cutInternals'],
'Symfony\Component\HttpClient\AmpHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClient'],
'Symfony\Component\HttpClient\Response\AmpResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castHttpClientResponse'],
'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castRequest'],
'Symfony\Component\Uid\Ulid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUlid'],
'Symfony\Component\Uid\Uuid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster', 'castUuid'],
'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castThrowingCasterException'],
'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castTraceStub'],
'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster', 'castFrameStub'],
@@ -147,8 +153,9 @@ abstract class AbstractCloner implements ClonerInterface
'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPair'],
'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster', 'castPairStub'],
'mysqli_driver' => ['Symfony\Component\VarDumper\Caster\MysqliCaster', 'castMysqliDriver'],
'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
':curl' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castCurl'],
':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster', 'castDba'],
@@ -190,10 +197,18 @@ abstract class AbstractCloner implements ClonerInterface
protected $maxString = -1;
protected $minDepth = 1;
private $casters = [];
/**
* @var array<string, list<callable>>
*/
private array $casters = [];
/**
* @var callable|null
*/
private $prevErrorHandler;
private $classInfo = [];
private $filter = 0;
private array $classInfo = [];
private int $filter = 0;
/**
* @param callable[]|null $casters A map of casters
@@ -253,12 +268,9 @@ abstract class AbstractCloner implements ClonerInterface
/**
* Clones a PHP variable.
*
* @param mixed $var Any PHP variable
* @param int $filter A bit field of Caster::EXCLUDE_* constants
*
* @return Data The cloned variable represented by a Data object
* @param int $filter A bit field of Caster::EXCLUDE_* constants
*/
public function cloneVar($var, int $filter = 0)
public function cloneVar(mixed $var, int $filter = 0): Data
{
$this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context = []) {
if (\E_RECOVERABLE_ERROR === $type || \E_USER_ERROR === $type) {
@@ -290,26 +302,20 @@ abstract class AbstractCloner implements ClonerInterface
/**
* Effectively clones the PHP variable.
*
* @param mixed $var Any PHP variable
*
* @return array The cloned variable represented in an array
*/
abstract protected function doClone($var);
abstract protected function doClone(mixed $var): array;
/**
* Casts an object to an array representation.
*
* @param bool $isNested True if the object is nested in the dumped structure
*
* @return array The object casted as array
*/
protected function castObject(Stub $stub, bool $isNested)
protected function castObject(Stub $stub, bool $isNested): array
{
$obj = $stub->value;
$class = $stub->class;
if (\PHP_VERSION_ID < 80000 ? "\0" === ($class[15] ?? null) : str_contains($class, "@anonymous\0")) {
if (str_contains($class, "@anonymous\0")) {
$stub->class = get_debug_type($obj);
}
if (isset($this->classInfo[$class])) {
@@ -360,10 +366,8 @@ abstract class AbstractCloner implements ClonerInterface
* Casts a resource to an array representation.
*
* @param bool $isNested True if the object is nested in the dumped structure
*
* @return array The resource casted as array
*/
protected function castResource(Stub $stub, bool $isNested)
protected function castResource(Stub $stub, bool $isNested): array
{
$a = [];
$res = $stub->value;

View File

@@ -18,10 +18,6 @@ interface ClonerInterface
{
/**
* Clones a PHP variable.
*
* @param mixed $var Any PHP variable
*
* @return Data The cloned variable represented by a Data object
*/
public function cloneVar($var);
public function cloneVar(mixed $var): Data;
}

View File

@@ -19,13 +19,13 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
*/
class Data implements \ArrayAccess, \Countable, \IteratorAggregate
{
private $data;
private $position = 0;
private $key = 0;
private $maxDepth = 20;
private $maxItemsPerDepth = -1;
private $useRefHandles = -1;
private $context = [];
private array $data;
private int $position = 0;
private int|string $key = 0;
private int $maxDepth = 20;
private int $maxItemsPerDepth = -1;
private int $useRefHandles = -1;
private array $context = [];
/**
* @param array $data An array as returned by ClonerInterface::cloneVar()
@@ -35,10 +35,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
$this->data = $data;
}
/**
* @return string|null The type of the value
*/
public function getType()
public function getType(): ?string
{
$item = $this->data[$this->position][$this->key];
@@ -65,11 +62,13 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
}
/**
* Returns a native representation of the original value.
*
* @param array|bool $recursive Whether values should be resolved recursively or not
*
* @return string|int|float|bool|array|Data[]|null A native representation of the original value
* @return string|int|float|bool|array|Data[]|null
*/
public function getValue($recursive = false)
public function getValue(array|bool $recursive = false): string|int|float|bool|array|null
{
$item = $this->data[$this->position][$this->key];
@@ -108,18 +107,12 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
return $children;
}
/**
* @return int
*/
public function count()
public function count(): int
{
return \count($this->getValue());
}
/**
* @return \Traversable
*/
public function getIterator()
public function getIterator(): \Traversable
{
if (!\is_array($value = $this->getValue())) {
throw new \LogicException(sprintf('"%s" object holds non-iterable type "%s".', self::class, get_debug_type($value)));
@@ -139,50 +132,32 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
return null;
}
/**
* @return bool
*/
public function __isset(string $key)
public function __isset(string $key): bool
{
return null !== $this->seek($key);
}
/**
* @return bool
*/
public function offsetExists($key)
public function offsetExists(mixed $key): bool
{
return $this->__isset($key);
}
/**
* @return mixed
*/
public function offsetGet($key)
public function offsetGet(mixed $key): mixed
{
return $this->__get($key);
}
/**
* @return void
*/
public function offsetSet($key, $value)
public function offsetSet(mixed $key, mixed $value): void
{
throw new \BadMethodCallException(self::class.' objects are immutable.');
}
/**
* @return void
*/
public function offsetUnset($key)
public function offsetUnset(mixed $key): void
{
throw new \BadMethodCallException(self::class.' objects are immutable.');
}
/**
* @return string
*/
public function __toString()
public function __toString(): string
{
$value = $this->getValue();
@@ -195,26 +170,22 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/**
* Returns a depth limited clone of $this.
*
* @return static
*/
public function withMaxDepth(int $maxDepth)
public function withMaxDepth(int $maxDepth): static
{
$data = clone $this;
$data->maxDepth = (int) $maxDepth;
$data->maxDepth = $maxDepth;
return $data;
}
/**
* Limits the number of elements per depth level.
*
* @return static
*/
public function withMaxItemsPerDepth(int $maxItemsPerDepth)
public function withMaxItemsPerDepth(int $maxItemsPerDepth): static
{
$data = clone $this;
$data->maxItemsPerDepth = (int) $maxItemsPerDepth;
$data->maxItemsPerDepth = $maxItemsPerDepth;
return $data;
}
@@ -223,10 +194,8 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
* Enables/disables objects' identifiers tracking.
*
* @param bool $useRefHandles False to hide global ref. handles
*
* @return static
*/
public function withRefHandles(bool $useRefHandles)
public function withRefHandles(bool $useRefHandles): static
{
$data = clone $this;
$data->useRefHandles = $useRefHandles ? -1 : 0;
@@ -234,10 +203,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
return $data;
}
/**
* @return static
*/
public function withContext(array $context)
public function withContext(array $context): static
{
$data = clone $this;
$data->context = $context;
@@ -247,12 +213,8 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
/**
* Seeks to a specific key in nested data structures.
*
* @param string|int $key The key to seek to
*
* @return static|null Null if the key is not set
*/
public function seek($key)
public function seek(string|int $key): ?static
{
$item = $this->data[$this->position][$this->key];
@@ -318,7 +280,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
*
* @param mixed $item A Stub object or the original value being dumped
*/
private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, $item)
private function dumpItem(DumperInterface $dumper, Cursor $cursor, array &$refs, mixed $item)
{
$cursor->refIndex = 0;
$cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
@@ -440,7 +402,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
return $hashCut;
}
private function getStub($item)
private function getStub(mixed $item)
{
if (!$item || !\is_array($item)) {
return $item;

View File

@@ -20,11 +20,8 @@ interface DumperInterface
{
/**
* Dumps a scalar value.
*
* @param string $type The PHP type of the value being dumped
* @param string|int|float|bool $value The scalar value being dumped
*/
public function dumpScalar(Cursor $cursor, string $type, $value);
public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value);
/**
* Dumps a string.
@@ -38,19 +35,19 @@ interface DumperInterface
/**
* Dumps while entering an hash.
*
* @param int $type A Cursor::HASH_* const for the type of hash
* @param string|int $class The object class, resource type or array count
* @param bool $hasChild When the dump of the hash has child item
* @param int $type A Cursor::HASH_* const for the type of hash
* @param string|int|null $class The object class, resource type or array count
* @param bool $hasChild When the dump of the hash has child item
*/
public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild);
public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild);
/**
* Dumps while leaving an hash.
*
* @param int $type A Cursor::HASH_* const for the type of hash
* @param string|int $class The object class, resource type or array count
* @param bool $hasChild When the dump of the hash has child item
* @param int $cut The number of items the hash has been cut by
* @param int $type A Cursor::HASH_* const for the type of hash
* @param string|int|null $class The object class, resource type or array count
* @param bool $hasChild When the dump of the hash has child item
* @param int $cut The number of items the hash has been cut by
*/
public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut);
public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut);
}

View File

@@ -39,7 +39,7 @@ class Stub
public $position = 0;
public $attr = [];
private static $defaultProperties = [];
private static array $defaultProperties = [];
/**
* @internal

View File

@@ -16,23 +16,23 @@ namespace Symfony\Component\VarDumper\Cloner;
*/
class VarCloner extends AbstractCloner
{
private static $gid;
private static $arrayCache = [];
private static string $gid;
private static array $arrayCache = [];
/**
* {@inheritdoc}
*/
protected function doClone($var)
protected function doClone(mixed $var): array
{
$len = 1; // Length of $queue
$pos = 0; // Number of cloned items past the minimum depth
$refsCounter = 0; // Hard references counter
$queue = [[$var]]; // This breadth-first queue is the return value
$hardRefs = []; // Map of original zval ids to stub objects
$objRefs = []; // Map of original object handles to their stub object counterpart
$objects = []; // Keep a ref to objects to ensure their handle cannot be reused while cloning
$resRefs = []; // Map of original resource handles to their stub object counterpart
$values = []; // Map of stub objects' ids to original values
$queue = [[$var]]; // This breadth-first queue is the return value
$hardRefs = []; // Map of original zval ids to stub objects
$objRefs = []; // Map of original object handles to their stub object counterpart
$objects = []; // Keep a ref to objects to ensure their handle cannot be reused while cloning
$resRefs = []; // Map of original resource handles to their stub object counterpart
$values = []; // Map of stub objects' ids to original values
$maxItems = $this->maxItems;
$maxString = $this->maxString;
$minDepth = $this->minDepth;
@@ -44,9 +44,7 @@ class VarCloner extends AbstractCloner
$stub = null; // Stub capturing the main properties of an original item value
// or null if the original value is used directly
if (!$gid = self::$gid) {
$gid = self::$gid = md5(random_bytes(6)); // Unique string used to detect the special $GLOBALS variable
}
$gid = self::$gid ??= md5(random_bytes(6)); // Unique string used to detect the special $GLOBALS variable
$arrayStub = new Stub();
$arrayStub->type = Stub::TYPE_ARRAY;
$fromObjCast = false;
@@ -65,32 +63,25 @@ class VarCloner extends AbstractCloner
foreach ($vals as $k => $v) {
// $v is the original value or a stub object in case of hard references
if (\PHP_VERSION_ID >= 70400) {
$zvalIsRef = null !== \ReflectionReference::fromArrayElement($vals, $k);
} else {
$refs[$k] = $cookie;
$zvalIsRef = $vals[$k] === $cookie;
}
$zvalRef = ($r = \ReflectionReference::fromArrayElement($vals, $k)) ? $r->getId() : null;
if ($zvalIsRef) {
if ($zvalRef) {
$vals[$k] = &$stub; // Break hard references to make $queue completely
unset($stub); // independent from the original structure
if ($v instanceof Stub && isset($hardRefs[spl_object_id($v)])) {
$vals[$k] = $refs[$k] = $v;
if (null !== $vals[$k] = $hardRefs[$zvalRef] ?? null) {
$v = $vals[$k];
if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) {
++$v->value->refCount;
}
++$v->refCount;
continue;
}
$refs[$k] = $vals[$k] = new Stub();
$refs[$k]->value = $v;
$h = spl_object_id($refs[$k]);
$hardRefs[$h] = &$refs[$k];
$values[$h] = $v;
$vals[$k] = new Stub();
$vals[$k]->value = $v;
$vals[$k]->handle = ++$refsCounter;
$hardRefs[$zvalRef] = $vals[$k];
}
// Create $stub when the original value $v can not be used directly
// Create $stub when the original value $v cannot be used directly
// If $v is a nested structure, put that structure in array $a
switch (true) {
case null === $v:
@@ -129,39 +120,46 @@ class VarCloner extends AbstractCloner
continue 2;
}
$stub = $arrayStub;
if (\PHP_VERSION_ID >= 80100) {
$stub->class = array_is_list($v) ? Stub::ARRAY_INDEXED : Stub::ARRAY_ASSOC;
$a = $v;
break;
}
$stub->class = Stub::ARRAY_INDEXED;
$j = -1;
foreach ($v as $gk => $gv) {
if ($gk !== ++$j) {
$stub->class = Stub::ARRAY_ASSOC;
$a = $v;
$a[$gid] = true;
break;
}
}
$a = $v;
if (Stub::ARRAY_ASSOC === $stub->class) {
// Copies of $GLOBALS have very strange behavior,
// let's detect them with some black magic
if (\PHP_VERSION_ID < 80100 && ($a[$gid] = true) && isset($v[$gid])) {
unset($v[$gid]);
$a = [];
foreach ($v as $gk => &$gv) {
if ($v === $gv) {
unset($v);
$v = new Stub();
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
$v->handle = -1;
$gv = &$hardRefs[spl_object_id($v)];
$gv = $v;
}
$a[$gk] = &$gv;
// Copies of $GLOBALS have very strange behavior,
// let's detect them with some black magic
if (isset($v[$gid])) {
unset($v[$gid]);
$a = [];
foreach ($v as $gk => &$gv) {
if ($v === $gv && !isset($hardRefs[\ReflectionReference::fromArrayElement($v, $gk)->getId()])) {
unset($v);
$v = new Stub();
$v->value = [$v->cut = \count($gv), Stub::TYPE_ARRAY => 0];
$v->handle = -1;
$gv = &$a[$gk];
$hardRefs[\ReflectionReference::fromArrayElement($a, $gk)->getId()] = &$gv;
$gv = $v;
}
unset($gv);
} else {
$a = $v;
$a[$gk] = &$gv;
}
unset($gv);
} else {
$a = $v;
}
break;
@@ -251,10 +249,10 @@ class VarCloner extends AbstractCloner
}
}
if ($zvalIsRef) {
$refs[$k]->value = $stub;
} else {
if (!$zvalRef) {
$vals[$k] = $stub;
} else {
$hardRefs[$zvalRef]->value = $stub;
}
}

View File

@@ -11,7 +11,6 @@
namespace Symfony\Component\VarDumper\Command\Descriptor;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
@@ -28,13 +27,11 @@ use Symfony\Component\VarDumper\Dumper\CliDumper;
class CliDescriptor implements DumpDescriptorInterface
{
private $dumper;
private $lastIdentifier;
private $supportsHref;
private mixed $lastIdentifier = null;
public function __construct(CliDumper $dumper)
{
$this->dumper = $dumper;
$this->supportsHref = method_exists(OutputFormatterStyle::class, 'setHref');
}
public function describe(OutputInterface $output, Data $data, array $context, int $clientId): void
@@ -66,8 +63,7 @@ class CliDescriptor implements DumpDescriptorInterface
if (isset($context['source'])) {
$source = $context['source'];
$sourceInfo = sprintf('%s on line %d', $source['name'], $source['line']);
$fileLink = $source['file_link'] ?? null;
if ($this->supportsHref && $fileLink) {
if ($fileLink = $source['file_link'] ?? null) {
$sourceInfo = sprintf('<href=%s>%s</>', $fileLink, $sourceInfo);
}
$rows[] = ['source', $sourceInfo];
@@ -77,11 +73,6 @@ class CliDescriptor implements DumpDescriptorInterface
$io->table([], $rows);
if (!$this->supportsHref && isset($fileLink)) {
$io->writeln(['<info>Open source in your IDE/browser:</info>', $fileLink]);
$io->newLine();
}
$this->dumper->dump($data);
$io->newLine();
}

View File

@@ -25,7 +25,7 @@ use Symfony\Component\VarDumper\Dumper\HtmlDumper;
class HtmlDescriptor implements DumpDescriptorInterface
{
private $dumper;
private $initialized = false;
private bool $initialized = false;
public function __construct(HtmlDumper $dumper)
{

View File

@@ -11,7 +11,10 @@
namespace Symfony\Component\VarDumper\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Completion\CompletionInput;
use Symfony\Component\Console\Completion\CompletionSuggestions;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -32,15 +35,13 @@ use Symfony\Component\VarDumper\Server\DumpServer;
*
* @final
*/
#[AsCommand(name: 'server:dump', description: 'Start a dump server that collects and displays dumps in a single place')]
class ServerDumpCommand extends Command
{
protected static $defaultName = 'server:dump';
protected static $defaultDescription = 'Start a dump server that collects and displays dumps in a single place';
private $server;
/** @var DumpDescriptorInterface[] */
private $descriptors;
private array $descriptors;
public function __construct(DumpServer $server, array $descriptors = [])
{
@@ -55,11 +56,8 @@ class ServerDumpCommand extends Command
protected function configure()
{
$availableFormats = implode(', ', array_keys($this->descriptors));
$this
->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', $availableFormats), 'cli')
->setDescription(self::$defaultDescription)
->addOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format (%s)', implode(', ', $this->getAvailableFormats())), 'cli')
->setHelp(<<<'EOF'
<info>%command.name%</info> starts a dump server that collects and displays
dumps in a single place for debugging you application:
@@ -99,4 +97,16 @@ EOF
return 0;
}
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
{
if ($input->mustSuggestOptionValuesFor('format')) {
$suggestions->suggestValues($this->getAvailableFormats());
}
}
private function getAvailableFormats(): array
{
return array_keys($this->descriptors);
}
}

View File

@@ -35,7 +35,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
protected $indentPad = ' ';
protected $flags;
private $charset = '';
private string $charset = '';
/**
* @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput
@@ -84,7 +84,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
*
* @return string The previous charset
*/
public function setCharset(string $charset)
public function setCharset(string $charset): string
{
$prev = $this->charset;
@@ -103,7 +103,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
*
* @return string The previous indent pad
*/
public function setIndentPad(string $pad)
public function setIndentPad(string $pad): string
{
$prev = $this->indentPad;
$this->indentPad = $pad;
@@ -118,7 +118,7 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
*
* @return string|null The dump as string when $output is true
*/
public function dump(Data $data, $output = null)
public function dump(Data $data, $output = null): ?string
{
$this->decimalPoint = localeconv();
$this->decimalPoint = $this->decimalPoint['decimal_point'];
@@ -179,10 +179,8 @@ abstract class AbstractDumper implements DataDumperInterface, DumperInterface
/**
* Converts a non-UTF-8 string to UTF-8.
*
* @return string|null The string converted to UTF-8
*/
protected function utf8Encode(?string $s)
protected function utf8Encode(?string $s): ?string
{
if (null === $s || preg_match('//u', $s)) {
return $s;

View File

@@ -55,11 +55,11 @@ class CliDumper extends AbstractDumper
protected $collapseNextHash = false;
protected $expandNextHash = false;
private $displayOptions = [
private array $displayOptions = [
'fileLinkFormat' => null,
];
private $handlesHrefGracefully;
private bool $handlesHrefGracefully;
/**
* {@inheritdoc}
@@ -125,7 +125,7 @@ class CliDumper extends AbstractDumper
/**
* {@inheritdoc}
*/
public function dumpScalar(Cursor $cursor, string $type, $value)
public function dumpScalar(Cursor $cursor, string $type, string|int|float|bool|null $value)
{
$this->dumpKey($cursor);
@@ -139,11 +139,20 @@ class CliDumper extends AbstractDumper
case 'integer':
$style = 'num';
if (isset($this->styles['integer'])) {
$style = 'integer';
}
break;
case 'double':
$style = 'num';
if (isset($this->styles['float'])) {
$style = 'float';
}
switch (true) {
case \INF === $value: $value = 'INF'; break;
case -\INF === $value: $value = '-INF'; break;
@@ -267,7 +276,7 @@ class CliDumper extends AbstractDumper
/**
* {@inheritdoc}
*/
public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild)
public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild)
{
if (null === $this->colors) {
$this->colors = $this->supportsColors();
@@ -308,7 +317,7 @@ class CliDumper extends AbstractDumper
/**
* {@inheritdoc}
*/
public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut)
public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut)
{
if (empty($cursor->attr['cut_hash'])) {
$this->dumpEllipsis($cursor, $hasChild, $cut);
@@ -425,19 +434,15 @@ class CliDumper extends AbstractDumper
* @param string $style The type of style being applied
* @param string $value The value being styled
* @param array $attr Optional context information
*
* @return string The value with style decoration
*/
protected function style(string $style, string $value, array $attr = [])
protected function style(string $style, string $value, array $attr = []): string
{
if (null === $this->colors) {
$this->colors = $this->supportsColors();
}
if (null === $this->handlesHrefGracefully) {
$this->handlesHrefGracefully = 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
}
$this->handlesHrefGracefully ??= 'JetBrains-JediTerm' !== getenv('TERMINAL_EMULATOR')
&& (!getenv('KONSOLE_VERSION') || (int) getenv('KONSOLE_VERSION') > 201100);
if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
$prefix = substr($value, 0, -$attr['ellipsis']);
@@ -501,10 +506,7 @@ class CliDumper extends AbstractDumper
return $value;
}
/**
* @return bool Tells if the current output stream supports ANSI colors or not
*/
protected function supportsColors()
protected function supportsColors(): bool
{
if ($this->outputStream !== static::$defaultOutput) {
return $this->hasColorSupport($this->outputStream);
@@ -576,10 +578,8 @@ class CliDumper extends AbstractDumper
*
* Reference: Composer\XdebugHandler\Process::supportsColor
* https://github.com/composer/xdebug-handler
*
* @param mixed $stream A CLI output stream
*/
private function hasColorSupport($stream): bool
private function hasColorSupport(mixed $stream): bool
{
if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) {
return false;

View File

@@ -18,8 +18,5 @@ namespace Symfony\Component\VarDumper\Dumper\ContextProvider;
*/
interface ContextProviderInterface
{
/**
* @return array|null Context data or null if unable to provide any context
*/
public function getContext(): ?array;
}

View File

@@ -25,9 +25,9 @@ use Twig\Template;
*/
final class SourceContextProvider implements ContextProviderInterface
{
private $limit;
private $charset;
private $projectDir;
private int $limit;
private ?string $charset;
private ?string $projectDir;
private $fileLinkFormatter;
public function __construct(string $charset = null, string $projectDir = null, FileLinkFormatter $fileLinkFormatter = null, int $limit = 9)

View File

@@ -20,7 +20,7 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
class ContextualizedDumper implements DataDumperInterface
{
private $wrappedDumper;
private $contextProviders;
private array $contextProviders;
/**
* @param ContextProviderInterface[] $contextProviders

View File

@@ -67,12 +67,12 @@ class HtmlDumper extends CliDumper
protected $lastDepth = -1;
protected $styles;
private $displayOptions = [
private array $displayOptions = [
'maxDepth' => 1,
'maxStringLength' => 160,
'fileLinkFormat' => null,
];
private $extraDisplayOptions = [];
private array $extraDisplayOptions = [];
/**
* {@inheritdoc}
@@ -134,7 +134,7 @@ class HtmlDumper extends CliDumper
/**
* {@inheritdoc}
*/
public function dump(Data $data, $output = null, array $extraDisplayOptions = [])
public function dump(Data $data, $output = null, array $extraDisplayOptions = []): ?string
{
$this->extraDisplayOptions = $extraDisplayOptions;
$result = parent::dump($data, $output);
@@ -803,7 +803,7 @@ EOHTML
/**
* {@inheritdoc}
*/
public function enterHash(Cursor $cursor, int $type, $class, bool $hasChild)
public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild)
{
if (Cursor::HASH_OBJECT === $type) {
$cursor->attr['depth'] = $cursor->depth;
@@ -834,7 +834,7 @@ EOHTML
/**
* {@inheritdoc}
*/
public function leaveHash(Cursor $cursor, int $type, $class, bool $hasChild, int $cut)
public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut)
{
$this->dumpEllipsis($cursor, $hasChild, $cut);
if ($hasChild) {
@@ -846,7 +846,7 @@ EOHTML
/**
* {@inheritdoc}
*/
protected function style(string $style, string $value, array $attr = [])
protected function style(string $style, string $value, array $attr = []): string
{
if ('' === $value) {
return '';

View File

@@ -1,4 +1,4 @@
Copyright (c) 2014-2021 Fabien Potencier
Copyright (c) 2014-2022 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -3,7 +3,7 @@ VarDumper Component
The VarDumper component provides mechanisms for walking through any arbitrary
PHP variable. It provides a better `dump()` function that you can use instead
of `var_dump`.
of `var_dump()`.
Resources
---------

View File

@@ -15,7 +15,7 @@ if (!function_exists('dump')) {
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
function dump($var, ...$moreVars)
function dump(mixed $var, mixed ...$moreVars): mixed
{
VarDumper::dump($var);
@@ -32,8 +32,15 @@ if (!function_exists('dump')) {
}
if (!function_exists('dd')) {
function dd(...$vars)
/**
* @return never
*/
function dd(...$vars): void
{
if (!in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
foreach ($vars as $v) {
VarDumper::dump($v);
}

View File

@@ -21,8 +21,12 @@ use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
*/
class Connection
{
private $host;
private $contextProviders;
private string $host;
private array $contextProviders;
/**
* @var resource|null
*/
private $socket;
/**

View File

@@ -24,10 +24,14 @@ use Symfony\Component\VarDumper\Cloner\Stub;
*/
class DumpServer
{
private $host;
private $socket;
private string $host;
private $logger;
/**
* @var resource|null
*/
private $socket;
public function __construct(string $host, LoggerInterface $logger = null)
{
if (!str_contains($host, '://')) {

View File

@@ -22,7 +22,7 @@ trait VarDumperTestTrait
/**
* @internal
*/
private $varDumperConfig = [
private array $varDumperConfig = [
'casters' => [],
'flags' => null,
];
@@ -42,17 +42,17 @@ trait VarDumperTestTrait
$this->varDumperConfig['flags'] = null;
}
public function assertDumpEquals($expected, $data, int $filter = 0, string $message = '')
public function assertDumpEquals(mixed $expected, mixed $data, int $filter = 0, string $message = '')
{
$this->assertSame($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
}
public function assertDumpMatchesFormat($expected, $data, int $filter = 0, string $message = '')
public function assertDumpMatchesFormat(mixed $expected, mixed $data, int $filter = 0, string $message = '')
{
$this->assertStringMatchesFormat($this->prepareExpectation($expected, $filter), $this->getDump($data, null, $filter), $message);
}
protected function getDump($data, $key = null, int $filter = 0): ?string
protected function getDump(mixed $data, string|int $key = null, int $filter = 0): ?string
{
if (null === $flags = $this->varDumperConfig['flags']) {
$flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0;
@@ -73,7 +73,7 @@ trait VarDumperTestTrait
return rtrim($dumper->dump($data, true));
}
private function prepareExpectation($expected, int $filter): string
private function prepareExpectation(mixed $expected, int $filter): string
{
if (!\is_string($expected)) {
$expected = $this->getDump($expected, null, $filter);

View File

@@ -32,9 +32,12 @@ require_once __DIR__.'/Resources/functions/dump.php';
*/
class VarDumper
{
/**
* @var callable|null
*/
private static $handler;
public static function dump($var)
public static function dump(mixed $var)
{
if (null === self::$handler) {
self::register();
@@ -43,7 +46,7 @@ class VarDumper
return (self::$handler)($var);
}
public static function setHandler(callable $callable = null)
public static function setHandler(callable $callable = null): ?callable
{
$prevHandler = self::$handler;

View File

@@ -16,19 +16,19 @@
}
],
"require": {
"php": ">=7.2.5",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16"
"php": ">=8.0.2",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^4.4|^5.0",
"symfony/process": "^4.4|^5.0",
"symfony/console": "^5.4|^6.0",
"symfony/process": "^5.4|^6.0",
"symfony/uid": "^5.4|^6.0",
"twig/twig": "^2.13|^3.0.4"
},
"conflict": {
"phpunit/phpunit": "<5.4.3",
"symfony/console": "<4.4"
"symfony/console": "<5.4"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",