1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
<?php /* * This file is part of Object Enumerator. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */
namespace SebastianBergmann\ObjectEnumerator;
use SebastianBergmann\RecursionContext\Context;
/** * Traverses array structures and object graphs * to enumerate all referenced objects. */ class Enumerator { /** * Returns an array of all objects referenced either * directly or indirectly by a variable. * * @param array|object $variable * * @return object[] */ public function enumerate($variable) { if (!is_array($variable) && !is_object($variable)) { throw new InvalidArgumentException; }
if (isset(func_get_args()[1])) { if (!func_get_args()[1] instanceof Context) { throw new InvalidArgumentException; }
$processed = func_get_args()[1]; } else { $processed = new Context; }
$objects = [];
if ($processed->contains($variable)) { return $objects; }
$array = $variable; $processed->add($variable);
if (is_array($variable)) { foreach ($array as $element) { if (!is_array($element) && !is_object($element)) { continue; }
$objects = array_merge( $objects, $this->enumerate($element, $processed) ); } } else { $objects[] = $variable; $reflector = new \ReflectionObject($variable);
foreach ($reflector->getProperties() as $attribute) { $attribute->setAccessible(true);
try { $value = $attribute->getValue($variable); } catch (\Throwable $e) { continue; } catch (\Exception $e) { continue; }
if (!is_array($value) && !is_object($value)) { continue; }
$objects = array_merge( $objects, $this->enumerate($value, $processed) ); } }
return $objects; } }
|