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