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

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 = array();
  21.     public static $prototypes = array();
  22.     public static $factories = array();
  23.     public static $cloneable = array();
  24.     public static $instantiableWithoutConstructor = array();
  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(array($reflector'newInstanceWithoutConstructor'));
  52.     }
  53.     public static function getClassReflector($class$instantiableWithoutConstructor false$cloneable null)
  54.     {
  55.         if (!\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 (!$reflector->isInstantiable()) {
  62.             throw new NotInstantiableTypeException($class);
  63.         } elseif ($reflector->name !== $class) {
  64.             $reflector self::$reflectors[$name $reflector->name] ?? self::getClassReflector($name$instantiableWithoutConstructor$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') ? 'C:' 'O:';
  75.                 if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) {
  76.                     $proto null;
  77.                 } elseif (false === $proto = @unserialize($proto.\strlen($class).':"'.$class.'":0:{}')) {
  78.                     throw new NotInstantiableTypeException($class);
  79.                 }
  80.             }
  81.             if (null !== $proto && !$proto instanceof \Throwable && !$proto instanceof \Serializable && !\method_exists($class'__sleep')) {
  82.                 try {
  83.                     serialize($proto);
  84.                 } catch (\Exception $e) {
  85.                     throw new NotInstantiableTypeException($class$e);
  86.                 }
  87.             }
  88.         }
  89.         if (null === $cloneable) {
  90.             if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !\method_exists($proto'__wakeup'))) {
  91.                 throw new NotInstantiableTypeException($class);
  92.             }
  93.             $cloneable $reflector->isCloneable() && !$reflector->hasMethod('__clone');
  94.         }
  95.         self::$cloneable[$class] = $cloneable;
  96.         self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor;
  97.         self::$prototypes[$class] = $proto;
  98.         if ($proto instanceof \Throwable) {
  99.             static $setTrace;
  100.             if (null === $setTrace) {
  101.                 $setTrace = array(
  102.                     new \ReflectionProperty(\Error::class, 'trace'),
  103.                     new \ReflectionProperty(\Exception::class, 'trace'),
  104.                 );
  105.                 $setTrace[0]->setAccessible(true);
  106.                 $setTrace[1]->setAccessible(true);
  107.                 $setTrace[0] = \Closure::fromCallable(array($setTrace[0], 'setValue'));
  108.                 $setTrace[1] = \Closure::fromCallable(array($setTrace[1], 'setValue'));
  109.             }
  110.             $setTrace[$proto instanceof \Exception]($proto, array());
  111.         }
  112.         return self::$reflectors[$class] = $reflector;
  113.     }
  114. }