<?php
declare(strict_types=1);
final class PathAsKeyDecorator implements \Iterator
{
private RecursiveIteratorIterator $inner;
public function __construct(RecursiveIteratorIterator $inner)
{
$this->inner = $inner;
}
public function current()
{
return $this->inner->current();
}
public function next(): void
{
$this->inner->next();
}
public function key()
{
$path = [];
for ($i = 0, $depth = $this->inner->getDepth(); $i <= $depth; $i++) {
$path[] = $this->inner->getSubIterator($i)->key();
}
return $path;
}
public function valid(): bool
{
return $this->inner->valid();
}
public function rewind(): void
{
$this->inner->rewind();
}
}
$input = [
'steve' => [
'id' => [
'#text' => 1,
],
],
'albert' => [
'id' => [
'#text' => 2,
],
],
'john' => [
'profil' => [
'id' => [
'#text' => 3,
],
],
],
];
// this is the filter function that should be customized given your requirements
// or create a factory function which produces these types of filter functions
$filter = static function ($current, array $path): bool {
// with help from the PathAsKeyDecorator
// we can decide on the path to the current value
return ['id', '#text'] === array_slice($path, -2)
// and the current value
&& 2 === $current;
};
// configure the iterator
$it = new CallbackFilterIterator(
new PathAsKeyDecorator(new RecursiveIteratorIterator(new RecursiveArrayIterator($input))),
$filter,
);
// traverse the iterator
foreach ($it as $path => $val) {
print_r([
'path' => $path,
'val' => $val
]);
}
Deprecated: Return type of PathAsKeyDecorator::current() should either be compatible with Iterator::current(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/fmrAk on line 13
Deprecated: Return type of PathAsKeyDecorator::key() should either be compatible with Iterator::key(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /in/fmrAk on line 23
Array
(
[path] => Array
(
[0] => albert
[1] => id
[2] => #text
)
[val] => 2
)
Output for 7.4.0 - 7.4.33, 8.0.0 - 8.0.30
Array
(
[path] => Array
(
[0] => albert
[1] => id
[2] => #text
)
[val] => 2
)
Output for 7.2.0 - 7.2.33, 7.3.0 - 7.3.33
Parse error: syntax error, unexpected 'RecursiveIteratorIterator' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST) in /in/fmrAk on line 6
Process exited with code 255.