vendor/symfony/var-dumper/Cloner/AbstractCloner.php line 277

Open in your IDE?
  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\Cloner;
  11. use Symfony\Component\VarDumper\Caster\Caster;
  12. use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
  13. /**
  14.  * AbstractCloner implements a generic caster mechanism for objects and resources.
  15.  *
  16.  * @author Nicolas Grekas <p@tchwork.com>
  17.  */
  18. abstract class AbstractCloner implements ClonerInterface
  19. {
  20.     public static $defaultCasters = [
  21.         '__PHP_Incomplete_Class' => ['Symfony\Component\VarDumper\Caster\Caster''castPhpIncompleteClass'],
  22.         'Symfony\Component\VarDumper\Caster\CutStub' => ['Symfony\Component\VarDumper\Caster\StubCaster''castStub'],
  23.         'Symfony\Component\VarDumper\Caster\CutArrayStub' => ['Symfony\Component\VarDumper\Caster\StubCaster''castCutArray'],
  24.         'Symfony\Component\VarDumper\Caster\ConstStub' => ['Symfony\Component\VarDumper\Caster\StubCaster''castStub'],
  25.         'Symfony\Component\VarDumper\Caster\EnumStub' => ['Symfony\Component\VarDumper\Caster\StubCaster''castEnum'],
  26.         'Fiber' => ['Symfony\Component\VarDumper\Caster\FiberCaster''castFiber'],
  27.         'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castClosure'],
  28.         'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castGenerator'],
  29.         'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castType'],
  30.         'ReflectionAttribute' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castAttribute'],
  31.         'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castReflectionGenerator'],
  32.         'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castClass'],
  33.         'ReflectionClassConstant' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castClassConstant'],
  34.         'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castFunctionAbstract'],
  35.         'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castMethod'],
  36.         'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castParameter'],
  37.         'ReflectionProperty' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castProperty'],
  38.         'ReflectionReference' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castReference'],
  39.         'ReflectionExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castExtension'],
  40.         'ReflectionZendExtension' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster''castZendExtension'],
  41.         'Doctrine\Common\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  42.         'Doctrine\Common\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster''castCommonProxy'],
  43.         'Doctrine\ORM\Proxy\Proxy' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster''castOrmProxy'],
  44.         'Doctrine\ORM\PersistentCollection' => ['Symfony\Component\VarDumper\Caster\DoctrineCaster''castPersistentCollection'],
  45.         'Doctrine\Persistence\ObjectManager' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  46.         'DOMException' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castException'],
  47.         'DOMStringList' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLength'],
  48.         'DOMNameList' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLength'],
  49.         'DOMImplementation' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castImplementation'],
  50.         'DOMImplementationList' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLength'],
  51.         'DOMNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castNode'],
  52.         'DOMNameSpaceNode' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castNameSpaceNode'],
  53.         'DOMDocument' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castDocument'],
  54.         'DOMNodeList' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLength'],
  55.         'DOMNamedNodeMap' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLength'],
  56.         'DOMCharacterData' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castCharacterData'],
  57.         'DOMAttr' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castAttr'],
  58.         'DOMElement' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castElement'],
  59.         'DOMText' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castText'],
  60.         'DOMTypeinfo' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castTypeinfo'],
  61.         'DOMDomError' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castDomError'],
  62.         'DOMLocator' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castLocator'],
  63.         'DOMDocumentType' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castDocumentType'],
  64.         'DOMNotation' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castNotation'],
  65.         'DOMEntity' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castEntity'],
  66.         'DOMProcessingInstruction' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castProcessingInstruction'],
  67.         'DOMXPath' => ['Symfony\Component\VarDumper\Caster\DOMCaster''castXPath'],
  68.         'XMLReader' => ['Symfony\Component\VarDumper\Caster\XmlReaderCaster''castXmlReader'],
  69.         'ErrorException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castErrorException'],
  70.         'Exception' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castException'],
  71.         'Error' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castError'],
  72.         'Symfony\Bridge\Monolog\Logger' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  73.         'Symfony\Component\DependencyInjection\ContainerInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  74.         'Symfony\Component\EventDispatcher\EventDispatcherInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  75.         'Symfony\Component\HttpClient\AmpHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClient'],
  76.         'Symfony\Component\HttpClient\CurlHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClient'],
  77.         'Symfony\Component\HttpClient\NativeHttpClient' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClient'],
  78.         'Symfony\Component\HttpClient\Response\AmpResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClientResponse'],
  79.         'Symfony\Component\HttpClient\Response\CurlResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClientResponse'],
  80.         'Symfony\Component\HttpClient\Response\NativeResponse' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castHttpClientResponse'],
  81.         'Symfony\Component\HttpFoundation\Request' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castRequest'],
  82.         'Symfony\Component\Uid\Ulid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castUlid'],
  83.         'Symfony\Component\Uid\Uuid' => ['Symfony\Component\VarDumper\Caster\SymfonyCaster''castUuid'],
  84.         'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castThrowingCasterException'],
  85.         'Symfony\Component\VarDumper\Caster\TraceStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castTraceStub'],
  86.         'Symfony\Component\VarDumper\Caster\FrameStub' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castFrameStub'],
  87.         'Symfony\Component\VarDumper\Cloner\AbstractCloner' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  88.         'Symfony\Component\ErrorHandler\Exception\SilencedErrorContext' => ['Symfony\Component\VarDumper\Caster\ExceptionCaster''castSilencedErrorContext'],
  89.         'Imagine\Image\ImageInterface' => ['Symfony\Component\VarDumper\Caster\ImagineCaster''castImage'],
  90.         'Ramsey\Uuid\UuidInterface' => ['Symfony\Component\VarDumper\Caster\UuidCaster''castRamseyUuid'],
  91.         'ProxyManager\Proxy\ProxyInterface' => ['Symfony\Component\VarDumper\Caster\ProxyManagerCaster''castProxy'],
  92.         'PHPUnit_Framework_MockObject_MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  93.         'PHPUnit\Framework\MockObject\MockObject' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  94.         'PHPUnit\Framework\MockObject\Stub' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  95.         'Prophecy\Prophecy\ProphecySubjectInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  96.         'Mockery\MockInterface' => ['Symfony\Component\VarDumper\Caster\StubCaster''cutInternals'],
  97.         'PDO' => ['Symfony\Component\VarDumper\Caster\PdoCaster''castPdo'],
  98.         'PDOStatement' => ['Symfony\Component\VarDumper\Caster\PdoCaster''castPdoStatement'],
  99.         'AMQPConnection' => ['Symfony\Component\VarDumper\Caster\AmqpCaster''castConnection'],
  100.         'AMQPChannel' => ['Symfony\Component\VarDumper\Caster\AmqpCaster''castChannel'],
  101.         'AMQPQueue' => ['Symfony\Component\VarDumper\Caster\AmqpCaster''castQueue'],
  102.         'AMQPExchange' => ['Symfony\Component\VarDumper\Caster\AmqpCaster''castExchange'],
  103.         'AMQPEnvelope' => ['Symfony\Component\VarDumper\Caster\AmqpCaster''castEnvelope'],
  104.         'ArrayObject' => ['Symfony\Component\VarDumper\Caster\SplCaster''castArrayObject'],
  105.         'ArrayIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster''castArrayIterator'],
  106.         'SplDoublyLinkedList' => ['Symfony\Component\VarDumper\Caster\SplCaster''castDoublyLinkedList'],
  107.         'SplFileInfo' => ['Symfony\Component\VarDumper\Caster\SplCaster''castFileInfo'],
  108.         'SplFileObject' => ['Symfony\Component\VarDumper\Caster\SplCaster''castFileObject'],
  109.         'SplHeap' => ['Symfony\Component\VarDumper\Caster\SplCaster''castHeap'],
  110.         'SplObjectStorage' => ['Symfony\Component\VarDumper\Caster\SplCaster''castObjectStorage'],
  111.         'SplPriorityQueue' => ['Symfony\Component\VarDumper\Caster\SplCaster''castHeap'],
  112.         'OuterIterator' => ['Symfony\Component\VarDumper\Caster\SplCaster''castOuterIterator'],
  113.         'WeakReference' => ['Symfony\Component\VarDumper\Caster\SplCaster''castWeakReference'],
  114.         'Redis' => ['Symfony\Component\VarDumper\Caster\RedisCaster''castRedis'],
  115.         'RedisArray' => ['Symfony\Component\VarDumper\Caster\RedisCaster''castRedisArray'],
  116.         'RedisCluster' => ['Symfony\Component\VarDumper\Caster\RedisCaster''castRedisCluster'],
  117.         'DateTimeInterface' => ['Symfony\Component\VarDumper\Caster\DateCaster''castDateTime'],
  118.         'DateInterval' => ['Symfony\Component\VarDumper\Caster\DateCaster''castInterval'],
  119.         'DateTimeZone' => ['Symfony\Component\VarDumper\Caster\DateCaster''castTimeZone'],
  120.         'DatePeriod' => ['Symfony\Component\VarDumper\Caster\DateCaster''castPeriod'],
  121.         'GMP' => ['Symfony\Component\VarDumper\Caster\GmpCaster''castGmp'],
  122.         'MessageFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster''castMessageFormatter'],
  123.         'NumberFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster''castNumberFormatter'],
  124.         'IntlTimeZone' => ['Symfony\Component\VarDumper\Caster\IntlCaster''castIntlTimeZone'],
  125.         'IntlCalendar' => ['Symfony\Component\VarDumper\Caster\IntlCaster''castIntlCalendar'],
  126.         'IntlDateFormatter' => ['Symfony\Component\VarDumper\Caster\IntlCaster''castIntlDateFormatter'],
  127.         'Memcached' => ['Symfony\Component\VarDumper\Caster\MemcachedCaster''castMemcached'],
  128.         'Ds\Collection' => ['Symfony\Component\VarDumper\Caster\DsCaster''castCollection'],
  129.         'Ds\Map' => ['Symfony\Component\VarDumper\Caster\DsCaster''castMap'],
  130.         'Ds\Pair' => ['Symfony\Component\VarDumper\Caster\DsCaster''castPair'],
  131.         'Symfony\Component\VarDumper\Caster\DsPairStub' => ['Symfony\Component\VarDumper\Caster\DsCaster''castPairStub'],
  132.         'mysqli_driver' => ['Symfony\Component\VarDumper\Caster\MysqliCaster''castMysqliDriver'],
  133.         'CurlHandle' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castCurl'],
  134.         ':curl' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castCurl'],
  135.         ':dba' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castDba'],
  136.         ':dba persistent' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castDba'],
  137.         'GdImage' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castGd'],
  138.         ':gd' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castGd'],
  139.         ':mysql link' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castMysqlLink'],
  140.         ':pgsql large object' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster''castLargeObject'],
  141.         ':pgsql link' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster''castLink'],
  142.         ':pgsql link persistent' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster''castLink'],
  143.         ':pgsql result' => ['Symfony\Component\VarDumper\Caster\PgSqlCaster''castResult'],
  144.         ':process' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castProcess'],
  145.         ':stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castStream'],
  146.         'OpenSSLCertificate' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castOpensslX509'],
  147.         ':OpenSSL X.509' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castOpensslX509'],
  148.         ':persistent stream' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castStream'],
  149.         ':stream-context' => ['Symfony\Component\VarDumper\Caster\ResourceCaster''castStreamContext'],
  150.         'XmlParser' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster''castXml'],
  151.         ':xml' => ['Symfony\Component\VarDumper\Caster\XmlResourceCaster''castXml'],
  152.         'RdKafka' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castRdKafka'],
  153.         'RdKafka\Conf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castConf'],
  154.         'RdKafka\KafkaConsumer' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castKafkaConsumer'],
  155.         'RdKafka\Metadata\Broker' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castBrokerMetadata'],
  156.         'RdKafka\Metadata\Collection' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castCollectionMetadata'],
  157.         'RdKafka\Metadata\Partition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castPartitionMetadata'],
  158.         'RdKafka\Metadata\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castTopicMetadata'],
  159.         'RdKafka\Message' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castMessage'],
  160.         'RdKafka\Topic' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castTopic'],
  161.         'RdKafka\TopicPartition' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castTopicPartition'],
  162.         'RdKafka\TopicConf' => ['Symfony\Component\VarDumper\Caster\RdKafkaCaster''castTopicConf'],
  163.     ];
  164.     protected $maxItems 2500;
  165.     protected $maxString = -1;
  166.     protected $minDepth 1;
  167.     /**
  168.      * @var array<string, list<callable>>
  169.      */
  170.     private $casters = [];
  171.     /**
  172.      * @var callable|null
  173.      */
  174.     private $prevErrorHandler;
  175.     private $classInfo = [];
  176.     private $filter 0;
  177.     /**
  178.      * @param callable[]|null $casters A map of casters
  179.      *
  180.      * @see addCasters
  181.      */
  182.     public function __construct(?array $casters null)
  183.     {
  184.         if (null === $casters) {
  185.             $casters = static::$defaultCasters;
  186.         }
  187.         $this->addCasters($casters);
  188.     }
  189.     /**
  190.      * Adds casters for resources and objects.
  191.      *
  192.      * Maps resources or objects types to a callback.
  193.      * Types are in the key, with a callable caster for value.
  194.      * Resource types are to be prefixed with a `:`,
  195.      * see e.g. static::$defaultCasters.
  196.      *
  197.      * @param callable[] $casters A map of casters
  198.      */
  199.     public function addCasters(array $casters)
  200.     {
  201.         foreach ($casters as $type => $callback) {
  202.             $this->casters[$type][] = $callback;
  203.         }
  204.     }
  205.     /**
  206.      * Sets the maximum number of items to clone past the minimum depth in nested structures.
  207.      */
  208.     public function setMaxItems(int $maxItems)
  209.     {
  210.         $this->maxItems $maxItems;
  211.     }
  212.     /**
  213.      * Sets the maximum cloned length for strings.
  214.      */
  215.     public function setMaxString(int $maxString)
  216.     {
  217.         $this->maxString $maxString;
  218.     }
  219.     /**
  220.      * Sets the minimum tree depth where we are guaranteed to clone all the items.  After this
  221.      * depth is reached, only setMaxItems items will be cloned.
  222.      */
  223.     public function setMinDepth(int $minDepth)
  224.     {
  225.         $this->minDepth $minDepth;
  226.     }
  227.     /**
  228.      * Clones a PHP variable.
  229.      *
  230.      * @param mixed $var    Any PHP variable
  231.      * @param int   $filter A bit field of Caster::EXCLUDE_* constants
  232.      *
  233.      * @return Data
  234.      */
  235.     public function cloneVar($varint $filter 0)
  236.     {
  237.         $this->prevErrorHandler set_error_handler(function ($type$msg$file$line$context = []) {
  238.             if (\E_RECOVERABLE_ERROR === $type || \E_USER_ERROR === $type) {
  239.                 // Cloner never dies
  240.                 throw new \ErrorException($msg0$type$file$line);
  241.             }
  242.             if ($this->prevErrorHandler) {
  243.                 return ($this->prevErrorHandler)($type$msg$file$line$context);
  244.             }
  245.             return false;
  246.         });
  247.         $this->filter $filter;
  248.         if ($gc gc_enabled()) {
  249.             gc_disable();
  250.         }
  251.         try {
  252.             return new Data($this->doClone($var));
  253.         } finally {
  254.             if ($gc) {
  255.                 gc_enable();
  256.             }
  257.             restore_error_handler();
  258.             $this->prevErrorHandler null;
  259.         }
  260.     }
  261.     /**
  262.      * Effectively clones the PHP variable.
  263.      *
  264.      * @param mixed $var Any PHP variable
  265.      *
  266.      * @return array
  267.      */
  268.     abstract protected function doClone($var);
  269.     /**
  270.      * Casts an object to an array representation.
  271.      *
  272.      * @param bool $isNested True if the object is nested in the dumped structure
  273.      *
  274.      * @return array
  275.      */
  276.     protected function castObject(Stub $stubbool $isNested)
  277.     {
  278.         $obj $stub->value;
  279.         $class $stub->class;
  280.         if (\PHP_VERSION_ID 80000 "\0" === ($class[15] ?? null) : str_contains($class"@anonymous\0")) {
  281.             $stub->class get_debug_type($obj);
  282.         }
  283.         if (isset($this->classInfo[$class])) {
  284.             [$i$parents$hasDebugInfo$fileInfo] = $this->classInfo[$class];
  285.         } else {
  286.             $i 2;
  287.             $parents = [$class];
  288.             $hasDebugInfo method_exists($class'__debugInfo');
  289.             foreach (class_parents($class) as $p) {
  290.                 $parents[] = $p;
  291.                 ++$i;
  292.             }
  293.             foreach (class_implements($class) as $p) {
  294.                 $parents[] = $p;
  295.                 ++$i;
  296.             }
  297.             $parents[] = '*';
  298.             $r = new \ReflectionClass($class);
  299.             $fileInfo $r->isInternal() || $r->isSubclassOf(Stub::class) ? [] : [
  300.                 'file' => $r->getFileName(),
  301.                 'line' => $r->getStartLine(),
  302.             ];
  303.             $this->classInfo[$class] = [$i$parents$hasDebugInfo$fileInfo];
  304.         }
  305.         $stub->attr += $fileInfo;
  306.         $a Caster::castObject($obj$class$hasDebugInfo$stub->class);
  307.         try {
  308.             while ($i--) {
  309.                 if (!empty($this->casters[$p $parents[$i]])) {
  310.                     foreach ($this->casters[$p] as $callback) {
  311.                         $a $callback($obj$a$stub$isNested$this->filter);
  312.                     }
  313.                 }
  314.             }
  315.         } catch (\Exception $e) {
  316.             $a = [(Stub::TYPE_OBJECT === $stub->type Caster::PREFIX_VIRTUAL '').'⚠' => new ThrowingCasterException($e)] + $a;
  317.         }
  318.         return $a;
  319.     }
  320.     /**
  321.      * Casts a resource to an array representation.
  322.      *
  323.      * @param bool $isNested True if the object is nested in the dumped structure
  324.      *
  325.      * @return array
  326.      */
  327.     protected function castResource(Stub $stubbool $isNested)
  328.     {
  329.         $a = [];
  330.         $res $stub->value;
  331.         $type $stub->class;
  332.         try {
  333.             if (!empty($this->casters[':'.$type])) {
  334.                 foreach ($this->casters[':'.$type] as $callback) {
  335.                     $a $callback($res$a$stub$isNested$this->filter);
  336.                 }
  337.             }
  338.         } catch (\Exception $e) {
  339.             $a = [(Stub::TYPE_OBJECT === $stub->type Caster::PREFIX_VIRTUAL '').'⚠' => new ThrowingCasterException($e)] + $a;
  340.         }
  341.         return $a;
  342.     }
  343. }