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

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