1 | <?php |
||
96 | class GroupbyIterator extends \IteratorIterator implements \Countable, \ArrayAccess |
||
97 | { |
||
98 | use ArrayAccessTrait; |
||
99 | use DebugInfoTrait; |
||
100 | use GetterTrait; |
||
101 | |||
102 | // Fluent interface traits |
||
103 | use AllTrait; |
||
104 | use AnyTrait; |
||
105 | use ChainTrait; |
||
106 | use CycleTrait; |
||
107 | use FilterTrait; |
||
108 | use FirstTrait; |
||
109 | use GroupByTrait; |
||
110 | use ItemsTrait; |
||
111 | use KeysTrait; |
||
112 | use LastTrait; |
||
113 | use MapByTrait; |
||
114 | use MapTrait; |
||
115 | use ReduceTrait; |
||
116 | use ReversedTrait; |
||
117 | use SliceTrait; |
||
118 | use SortedTrait; |
||
119 | use ToArrayTrait; |
||
120 | use UniqueTrait; |
||
121 | use ValuesTrait; |
||
122 | use ZipTrait; |
||
123 | |||
124 | 13 | public function __construct(\Closure $func, \Iterator $iterable) |
|
125 | { |
||
126 | // todo: this implementation pre-computes everything... this is |
||
127 | // not the way an iterator should work. Please re-write. |
||
128 | 13 | $groupedIterator = null; |
|
129 | 13 | $previousGroupKey = null; |
|
130 | 13 | $data = array(); |
|
131 | |||
132 | 13 | foreach ($iterable as $key => $value) { |
|
133 | 13 | $groupKey = call_user_func($func, $value, $key); |
|
134 | 13 | if ($previousGroupKey !== $groupKey || $groupedIterator === null) { |
|
135 | 13 | $previousGroupKey = $groupKey; |
|
136 | 13 | $groupedIterator = new GroupedIterator($groupKey); |
|
137 | 13 | $data [] = $groupedIterator; |
|
138 | } |
||
139 | 13 | $groupedIterator->append($key, $value); |
|
140 | } |
||
141 | |||
142 | 13 | parent::__construct(new \ArrayIterator($data)); |
|
143 | 13 | } |
|
144 | |||
145 | 12 | public function key() |
|
149 | |||
150 | 11 | public function count() |
|
154 | |||
155 | /** |
||
156 | * @{inheritDoc} |
||
157 | */ |
||
158 | public function toArray() |
||
170 | } |
||
171 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: