[VarExporter] fix more edge cases
This commit is contained in:
parent
deae538245
commit
443bd119b1
@ -77,19 +77,7 @@ class Exporter
|
||||
$properties = array();
|
||||
$sleep = null;
|
||||
$arrayValue = (array) $value;
|
||||
|
||||
if (!isset(Registry::$reflectors[$class])) {
|
||||
Registry::getClassReflector($class);
|
||||
try {
|
||||
serialize(Registry::$prototypes[$class]);
|
||||
} catch (\Exception $e) {
|
||||
throw new NotInstantiableTypeException($class, $e);
|
||||
}
|
||||
if (\method_exists($class, '__sleep')) {
|
||||
Registry::getClassReflector($class, Registry::$instantiableWithoutConstructor[$class], Registry::$cloneable[$class]);
|
||||
}
|
||||
}
|
||||
$reflector = Registry::$reflectors[$class];
|
||||
$reflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);
|
||||
$proto = Registry::$prototypes[$class];
|
||||
|
||||
if (($value instanceof \ArrayIterator || $value instanceof \ArrayObject) && null !== $proto) {
|
||||
@ -133,7 +121,7 @@ class Exporter
|
||||
foreach ($arrayValue as $name => $v) {
|
||||
$n = (string) $name;
|
||||
if ('' === $n || "\0" !== $n[0]) {
|
||||
$c = '*';
|
||||
$c = 'stdClass';
|
||||
$properties[$c][$n] = $v;
|
||||
unset($sleep[$n]);
|
||||
} elseif ('*' === $n[1]) {
|
||||
@ -305,7 +293,7 @@ class Exporter
|
||||
$code .= $subIndent.(1 !== $k - $j ? $k.' => ' : '');
|
||||
$j = $k;
|
||||
$eol = ",\n";
|
||||
$c = '[\\'.$class.'::class]';
|
||||
$c = '['.self::export($class).']';
|
||||
|
||||
if ($seen[$class] ?? false) {
|
||||
if (Registry::$cloneable[$class]) {
|
||||
@ -351,8 +339,7 @@ class Exporter
|
||||
{
|
||||
$code = '';
|
||||
foreach ($value->properties as $class => $properties) {
|
||||
$c = '*' !== $class ? '\\'.$class.'::class' : "'*'";
|
||||
$code .= $subIndent.' '.$c.' => '.self::export($properties, $subIndent.' ').",\n";
|
||||
$code .= $subIndent.' '.self::export($class).' => '.self::export($properties, $subIndent.' ').",\n";
|
||||
}
|
||||
|
||||
$code = array(
|
||||
|
@ -49,7 +49,7 @@ class Hydrator
|
||||
|
||||
public static function getHydrator($class)
|
||||
{
|
||||
if ('*' === $class) {
|
||||
if ('stdClass' === $class) {
|
||||
return self::$hydrators[$class] = static function ($properties, $objects) {
|
||||
foreach ($properties as $name => $values) {
|
||||
foreach ($values as $i => $v) {
|
||||
@ -62,13 +62,17 @@ class Hydrator
|
||||
$classReflector = Registry::$reflectors[$class] ?? Registry::getClassReflector($class);
|
||||
|
||||
if (!$classReflector->isInternal()) {
|
||||
return self::$hydrators[$class] = (self::$hydrators['*'] ?? self::getHydrator('*'))->bindTo(null, $class);
|
||||
return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, $class);
|
||||
}
|
||||
|
||||
if ($classReflector->name !== $class) {
|
||||
return self::$hydrators[$classReflector->name] ?? self::getHydrator($classReflector->name);
|
||||
}
|
||||
|
||||
switch ($class) {
|
||||
case 'ArrayIterator':
|
||||
case 'ArrayObject':
|
||||
$constructor = $classReflector->getConstructor();
|
||||
$constructor = \Closure::fromCallable(array($classReflector->getConstructor(), 'invokeArgs'));
|
||||
|
||||
return self::$hydrators[$class] = static function ($properties, $objects) use ($constructor) {
|
||||
foreach ($properties as $name => $values) {
|
||||
@ -78,17 +82,17 @@ class Hydrator
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($properties["\0"] as $i => $v) {
|
||||
$constructor->invokeArgs($objects[$i], $v);
|
||||
foreach ($properties["\0"] ?? array() as $i => $v) {
|
||||
$constructor($objects[$i], $v);
|
||||
}
|
||||
};
|
||||
|
||||
case 'ErrorException':
|
||||
return self::$hydrators[$class] = (self::$hydrators['*'] ?? self::getHydrator('*'))->bindTo(null, new class() extends \ErrorException {
|
||||
return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \ErrorException {
|
||||
});
|
||||
|
||||
case 'TypeError':
|
||||
return self::$hydrators[$class] = (self::$hydrators['*'] ?? self::getHydrator('*'))->bindTo(null, new class() extends \Error {
|
||||
return self::$hydrators[$class] = (self::$hydrators['stdClass'] ?? self::getHydrator('stdClass'))->bindTo(null, new class() extends \Error {
|
||||
});
|
||||
|
||||
case 'SplObjectStorage':
|
||||
@ -109,19 +113,28 @@ class Hydrator
|
||||
};
|
||||
}
|
||||
|
||||
$propertyReflectors = array();
|
||||
$propertySetters = array();
|
||||
foreach ($classReflector->getProperties() as $propertyReflector) {
|
||||
if (!$propertyReflector->isStatic()) {
|
||||
$propertyReflector->setAccessible(true);
|
||||
$propertyReflectors[$propertyReflector->name] = $propertyReflector;
|
||||
$propertySetters[$propertyReflector->name] = \Closure::fromCallable(array($propertyReflector, 'setValue'));
|
||||
}
|
||||
}
|
||||
|
||||
return self::$hydrators[$class] = static function ($properties, $objects) use ($propertyReflectors) {
|
||||
if (!$propertySetters) {
|
||||
return self::$hydrators[$class] = self::$hydrators['stdClass'] ?? self::getHydrator('stdClass');
|
||||
}
|
||||
|
||||
return self::$hydrators[$class] = static function ($properties, $objects) use ($propertySetters) {
|
||||
foreach ($properties as $name => $values) {
|
||||
$p = $propertyReflectors[$name];
|
||||
if ($setValue = $propertySetters[$name] ?? null) {
|
||||
foreach ($values as $i => $v) {
|
||||
$setValue($objects[$i], $v);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
foreach ($values as $i => $v) {
|
||||
$p->setValue($objects[$i], $v);
|
||||
$objects[$i]->$name = $v;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -65,17 +65,26 @@ class Registry
|
||||
|
||||
public static function getClassReflector($class, $instantiableWithoutConstructor = false, $cloneable = null)
|
||||
{
|
||||
if (!\class_exists($class)) {
|
||||
if (!\class_exists($class) && !\interface_exists($class, false) && !\trait_exists($class, false)) {
|
||||
throw new ClassNotFoundException($class);
|
||||
}
|
||||
$reflector = new \ReflectionClass($class);
|
||||
|
||||
if (self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor || !$reflector->isFinal()) {
|
||||
if ($instantiableWithoutConstructor) {
|
||||
$proto = $reflector->newInstanceWithoutConstructor();
|
||||
} elseif (!$reflector->isInstantiable()) {
|
||||
throw new NotInstantiableTypeException($class);
|
||||
} elseif ($reflector->name !== $class) {
|
||||
$reflector = self::$reflectors[$name = $reflector->name] ?? self::getClassReflector($name, $instantiableWithoutConstructor, $cloneable);
|
||||
self::$cloneable[$class] = self::$cloneable[$name];
|
||||
self::$instantiableWithoutConstructor[$class] = self::$instantiableWithoutConstructor[$name];
|
||||
self::$prototypes[$class] = self::$prototypes[$name];
|
||||
|
||||
return self::$reflectors[$class] = $reflector;
|
||||
} else {
|
||||
try {
|
||||
$proto = $reflector->newInstanceWithoutConstructor();
|
||||
self::$instantiableWithoutConstructor[$class] = true;
|
||||
$instantiableWithoutConstructor = true;
|
||||
} catch (\ReflectionException $e) {
|
||||
$proto = $reflector->implementsInterface('Serializable') ? 'C:' : 'O:';
|
||||
if ('C:' === $proto && !$reflector->getMethod('unserialize')->isInternal()) {
|
||||
@ -84,31 +93,48 @@ class Registry
|
||||
throw new NotInstantiableTypeException($class);
|
||||
}
|
||||
}
|
||||
if (null !== $proto && !$proto instanceof \Throwable) {
|
||||
try {
|
||||
if (!$proto instanceof \Serializable && !\method_exists($class, '__sleep')) {
|
||||
serialize($proto);
|
||||
} elseif ($instantiableWithoutConstructor) {
|
||||
serialize($reflector->newInstanceWithoutConstructor());
|
||||
} else {
|
||||
serialize(unserialize(($proto instanceof \Serializable ? 'C:' : 'O:').\strlen($class).':"'.$class.'":0:{}'));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new NotInstantiableTypeException($class, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null === self::$cloneable[$class] = $cloneable) {
|
||||
if (null === $cloneable) {
|
||||
if (($proto instanceof \Reflector || $proto instanceof \ReflectionGenerator || $proto instanceof \ReflectionType || $proto instanceof \IteratorIterator || $proto instanceof \RecursiveIteratorIterator) && (!$proto instanceof \Serializable && !\method_exists($proto, '__wakeup'))) {
|
||||
throw new NotInstantiableTypeException($class);
|
||||
}
|
||||
|
||||
self::$cloneable[$class] = $reflector->isCloneable() && !$reflector->hasMethod('__clone');
|
||||
$cloneable = $reflector->isCloneable() && !$reflector->hasMethod('__clone');
|
||||
}
|
||||
|
||||
self::$cloneable[$class] = $cloneable;
|
||||
self::$instantiableWithoutConstructor[$class] = $instantiableWithoutConstructor;
|
||||
self::$prototypes[$class] = $proto;
|
||||
|
||||
if ($proto instanceof \Throwable) {
|
||||
static $trace;
|
||||
static $setTrace;
|
||||
|
||||
if (null === $trace) {
|
||||
$trace = array(
|
||||
if (null === $setTrace) {
|
||||
$setTrace = array(
|
||||
new \ReflectionProperty(\Error::class, 'trace'),
|
||||
new \ReflectionProperty(\Exception::class, 'trace'),
|
||||
);
|
||||
$trace[0]->setAccessible(true);
|
||||
$trace[1]->setAccessible(true);
|
||||
$setTrace[0]->setAccessible(true);
|
||||
$setTrace[1]->setAccessible(true);
|
||||
$setTrace[0] = \Closure::fromCallable(array($setTrace[0], 'setValue'));
|
||||
$setTrace[1] = \Closure::fromCallable(array($setTrace[1], 'setValue'));
|
||||
}
|
||||
|
||||
$trace[$proto instanceof \Exception]->setValue($proto, array());
|
||||
$setTrace[$proto instanceof \Exception]($proto, array());
|
||||
}
|
||||
|
||||
return self::$reflectors[$class] = $reflector;
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes[\ArrayIterator::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\ArrayIterator::class)),
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['ArrayIterator'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayIterator')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
\ArrayIterator::class => [
|
||||
'ArrayIterator' => [
|
||||
"\0" => [
|
||||
[
|
||||
[
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes[\Symfony\Component\VarExporter\Tests\MyArrayObject::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\Symfony\Component\VarExporter\Tests\MyArrayObject::class)),
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['Symfony\\Component\\VarExporter\\Tests\\MyArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\MyArrayObject')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
\ArrayObject::class => [
|
||||
'ArrayObject' => [
|
||||
"\0" => [
|
||||
[
|
||||
[
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)[\ArrayObject::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\ArrayObject::class)),
|
||||
clone $p[\ArrayObject::class],
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['ArrayObject'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('ArrayObject')),
|
||||
clone $p['ArrayObject'],
|
||||
],
|
||||
null,
|
||||
[
|
||||
\ArrayObject::class => [
|
||||
'ArrayObject' => [
|
||||
"\0" => [
|
||||
[
|
||||
[
|
||||
@ -18,7 +18,7 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
],
|
||||
],
|
||||
],
|
||||
'*' => [
|
||||
'stdClass' => [
|
||||
'foo' => [
|
||||
$o[1],
|
||||
],
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
(($f = &\Symfony\Component\VarExporter\Internal\Registry::$factories)[\Symfony\Component\VarExporter\Tests\MyCloneable::class] ?? \Symfony\Component\VarExporter\Internal\Registry::f(\Symfony\Component\VarExporter\Tests\MyCloneable::class))(),
|
||||
($f[\Symfony\Component\VarExporter\Tests\MyNotCloneable::class] ?? \Symfony\Component\VarExporter\Internal\Registry::f(\Symfony\Component\VarExporter\Tests\MyNotCloneable::class))(),
|
||||
(($f = &\Symfony\Component\VarExporter\Internal\Registry::$factories)['Symfony\\Component\\VarExporter\\Tests\\MyCloneable'] ?? \Symfony\Component\VarExporter\Internal\Registry::f('Symfony\\Component\\VarExporter\\Tests\\MyCloneable'))(),
|
||||
($f['Symfony\\Component\\VarExporter\\Tests\\MyNotCloneable'] ?? \Symfony\Component\VarExporter\Internal\Registry::f('Symfony\\Component\\VarExporter\\Tests\\MyNotCloneable'))(),
|
||||
],
|
||||
null,
|
||||
[],
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes[\DateTime::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\DateTime::class)),
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['DateTime'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('DateTime')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
'*' => [
|
||||
'stdClass' => [
|
||||
'date' => [
|
||||
'1970-01-01 00:00:00.000000',
|
||||
],
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
(\Symfony\Component\VarExporter\Internal\Registry::$factories[\Error::class] ?? \Symfony\Component\VarExporter\Internal\Registry::f(\Error::class))(),
|
||||
(\Symfony\Component\VarExporter\Internal\Registry::$factories['Error'] ?? \Symfony\Component\VarExporter\Internal\Registry::f('Error'))(),
|
||||
],
|
||||
null,
|
||||
[
|
||||
\TypeError::class => [
|
||||
'TypeError' => [
|
||||
'file' => [
|
||||
\dirname(__DIR__).\DIRECTORY_SEPARATOR.'VarExporterTest.php',
|
||||
],
|
||||
@ -14,7 +14,7 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
234,
|
||||
],
|
||||
],
|
||||
\Error::class => [
|
||||
'Error' => [
|
||||
'trace' => [
|
||||
[
|
||||
'file' => \dirname(__DIR__).\DIRECTORY_SEPARATOR.'VarExporterTest.php',
|
||||
|
@ -6,7 +6,7 @@ return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
]),
|
||||
null,
|
||||
[
|
||||
\TypeError::class => [
|
||||
'TypeError' => [
|
||||
'file' => [
|
||||
\dirname(__DIR__).\DIRECTORY_SEPARATOR.'VarExporterTest.php',
|
||||
],
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
(\Symfony\Component\VarExporter\Internal\Registry::$factories[\Symfony\Component\VarExporter\Tests\FinalStdClass::class] ?? \Symfony\Component\VarExporter\Internal\Registry::f(\Symfony\Component\VarExporter\Tests\FinalStdClass::class))(),
|
||||
(\Symfony\Component\VarExporter\Internal\Registry::$factories['Symfony\\Component\\VarExporter\\Tests\\FinalStdClass'] ?? \Symfony\Component\VarExporter\Internal\Registry::f('Symfony\\Component\\VarExporter\\Tests\\FinalStdClass'))(),
|
||||
],
|
||||
null,
|
||||
[],
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes[\stdClass::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\stdClass::class)),
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['stdClass'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('stdClass')),
|
||||
],
|
||||
[
|
||||
$r = [],
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)[\Symfony\Component\VarExporter\Tests\MyPrivateValue::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\Symfony\Component\VarExporter\Tests\MyPrivateValue::class)),
|
||||
clone ($p[\Symfony\Component\VarExporter\Tests\MyPrivateChildValue::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\Symfony\Component\VarExporter\Tests\MyPrivateChildValue::class)),
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['Symfony\\Component\\VarExporter\\Tests\\MyPrivateValue'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\MyPrivateValue')),
|
||||
clone ($p['Symfony\\Component\\VarExporter\\Tests\\MyPrivateChildValue'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\MyPrivateChildValue')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
\Symfony\Component\VarExporter\Tests\MyPrivateValue::class => [
|
||||
'Symfony\\Component\\VarExporter\\Tests\\MyPrivateValue' => [
|
||||
'prot' => [
|
||||
123,
|
||||
123,
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)[\SplObjectStorage::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\SplObjectStorage::class)),
|
||||
clone ($p[\stdClass::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\stdClass::class)),
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['SplObjectStorage'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('SplObjectStorage')),
|
||||
clone ($p['stdClass'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('stdClass')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
\SplObjectStorage::class => [
|
||||
'SplObjectStorage' => [
|
||||
"\0" => [
|
||||
[
|
||||
$o[1],
|
||||
|
@ -2,11 +2,11 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes[\Symfony\Component\VarExporter\Tests\GoodNight::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\Symfony\Component\VarExporter\Tests\GoodNight::class)),
|
||||
clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['Symfony\\Component\\VarExporter\\Tests\\GoodNight'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\GoodNight')),
|
||||
],
|
||||
null,
|
||||
[
|
||||
'*' => [
|
||||
'stdClass' => [
|
||||
'good' => [
|
||||
'night',
|
||||
],
|
||||
|
@ -2,12 +2,12 @@
|
||||
|
||||
return \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
|
||||
$o = [
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)[\Symfony\Component\VarExporter\Tests\MyWakeup::class] ?? \Symfony\Component\VarExporter\Internal\Registry::p(\Symfony\Component\VarExporter\Tests\MyWakeup::class)),
|
||||
clone $p[\Symfony\Component\VarExporter\Tests\MyWakeup::class],
|
||||
clone (($p = &\Symfony\Component\VarExporter\Internal\Registry::$prototypes)['Symfony\\Component\\VarExporter\\Tests\\MyWakeup'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('Symfony\\Component\\VarExporter\\Tests\\MyWakeup')),
|
||||
clone $p['Symfony\\Component\\VarExporter\\Tests\\MyWakeup'],
|
||||
],
|
||||
null,
|
||||
[
|
||||
'*' => [
|
||||
'stdClass' => [
|
||||
'sub' => [
|
||||
$o[1],
|
||||
123,
|
||||
|
@ -61,6 +61,11 @@ class VarExporterTest extends TestCase
|
||||
yield array($h = fopen(__FILE__, 'r'));
|
||||
yield array(array($h));
|
||||
|
||||
$a = new class() {
|
||||
};
|
||||
|
||||
yield array($a);
|
||||
|
||||
$a = array(null, $h);
|
||||
$a[0] = &$a;
|
||||
|
||||
|
Reference in New Issue
Block a user