vendor/symfony/var-exporter/Internal/Registry.php line 52

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\VarExporter\Internal;
  11. use Symfony\Component\VarExporter\Exception\ClassNotFoundException;
  12. use Symfony\Component\VarExporter\Exception\NotInstantiableTypeException;
  13. /**
  14.  * @author Nicolas Grekas <p@tchwork.com>
  15.  *
  16.  * @internal
  17.  */
  18. class Registry
  19. {
  20.     public static array $reflectors = [];
  21.     public static array $prototypes = [];
  22.     public static array $factories = [];
  23.     public static array $cloneable = [];
  24.     public static array $instantiableWithoutConstructor = [];
  25.     public function __construct(
  26.         public readonly array $classes,
  27.     ) {
  28.     }
  29.     public static function unserialize($objects$serializables)
  30.     {
  31.         $unserializeCallback ini_set('unserialize_callback_func'__CLASS__.'::getClassReflector');
  32.         try {
  33.             foreach ($serializables as $k => $v) {
  34.                 $objects[$k] = unserialize($v);
  35.             }
  36.         } finally {
  37.             ini_set('unserialize_callback_func'$unserializeCallback);
  38.         }
  39.         return $objects;
  40.     }
  41.     public static function p($class)
  42.     {
  43.         self::getClassReflector($classtruetrue);
  44.         return self::$prototypes[$class];
  45.     }
  46.     public static function f($class)
  47.     {
  48.         $reflector self::$reflectors[$class] ??= self::getClassReflector($classtruefalse);
  49.         return self::$factories[$class] = $reflector->newInstanceWithoutConstructor(...);
  50.     }
  51.     public static function getClassReflector($class$instantiableWithoutConstructor false$cloneable null)
  52.     {
  53.         if (!($isClass class_exists($class)) && !interface_exists($classfalse) && !trait_exists($classfalse)) {
  54.             throw new ClassNotFoundException($class);
  55.         }
  56.         $reflector = new \ReflectionClass($class);
  57.         if ($instantiableWithoutConstructor) {
  58.             $proto $reflector->newInstanceWithoutConstructor();
  59.         } elseif (!$isClass || $reflector->isAbstract()) {
  60.             throw new NotInstantiableTypeException($class);
  61.         } elseif ($reflector->name !== $class) {
  62.             $reflector self::$reflectors[$name $reflector->name] ??= self::getClassReflector($namefalse$cloneable);
  63.             self::$cloneable[$class] = self::$cloneable[$name];
  64.             self::$instantiableWithoutConstructor[$class] = self::$instantiableWithoutConstructor[$name];
  65.             self::$prototypes[$class] = self::$prototypes[$name];
  66.             return $reflector;
  67.         } else {
  68.             try {
  69.                 $proto $reflector->newInstanceWithoutConstructor();
  70.                 $instantiableWithoutConstructor true;
  71.             } catch (\ReflectionException) {
  72.                 $proto $reflector->implementsInterface('Serializable') && !method_exists($class'__unserialize') ? 'C:' 'O:';
  73.                 if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) {
  74.                     $proto null;
  75.                 } else {
  76.                     try {
  77.                         $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}');
  78.                     } catch (\Exception $e) {
  79.                         if (__FILE__ !== $e->getFile()) {
  80.                             throw $e;
  81.                         }
  82.                         throw new NotInstantiableTypeException($class$e);
  83.                     }
  84.                     if (false === $proto) {
  85.                         throw new NotInstantiableTypeException($class);
  86.                     }
  87.                 }
  88.             }
  89.             if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !method_exists($class'__sleep') && !method_exists($class'__serialize')) {
  90.                 try {
  91.                     serialize($proto);
  92.                 } catch (\Exception $e) {
  93.                     throw new NotInstantiableTypeException($class$e);
  94.                 }
  95.             }
  96.         }
  97.         if (null === $cloneable) {
  98.             if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !method_exists($proto'__wakeup') && !method_exists($class'__unserialize'))) {
  99.                 throw new NotInstantiableTypeException($class);
  100.             }
  101.             $cloneable $reflector->isCloneable() && !$reflector->hasMethod('__clone');
  102.         }
  103.         self::$cloneable[$class] = $cloneable;
  104.         self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor;
  105.         self::$prototypes[$class] = $proto;
  106.         if ($proto instanceof \Throwable) {
  107.             static $setTrace;
  108.             if (null === $setTrace) {
  109.                 $setTrace = [
  110.                     new \ReflectionProperty(\Error::class, 'trace'),
  111.                     new \ReflectionProperty(\Exception::class, 'trace'),
  112.                 ];
  113.                 $setTrace[0] = $setTrace[0]->setValue(...);
  114.                 $setTrace[1] = $setTrace[1]->setValue(...);
  115.             }
  116.             $setTrace[$proto instanceof \Exception]($proto, []);
  117.         }
  118.         return $reflector;
  119.     }
  120. }