Вам необходимо вызвать getSubIterator
на текущей глубине, использовать offsetSet
на этой глубине и сделать то же самое для всех глубин, возвращающихся вверх по дереву.
Это действительно полезно для выполнения слияния и замены массивов неограниченного уровня для массивов или значений в массивах. К сожалению, array_walk_recursive
НЕ будет работать в этом случае, так как эта функция посещает только конечные узлы .. поэтому ключ replace_this_array в массиве $ ниже никогда не будет посещен.
В качестве примера, чтобы заменить все значения в массиве на неизвестные уровни глубиной, но только на те, которые содержат определенный ключ, вы должны сделать следующее:
$array = [
'test' => 'value',
'level_one' => [
'level_two' => [
'level_three' => [
'replace_this_array' => [
'special_key' => 'replacement_value',
'key_one' => 'testing',
'key_two' => 'value',
'four' => 'another value'
]
],
'ordinary_key' => 'value'
]
]
];
$arrayIterator = new \RecursiveArrayIterator($array);
$completeIterator = new \RecursiveIteratorIterator($arrayIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($completeIterator as $key => $value) {
if (is_array($value) && array_key_exists('special_key', $value)) {
// Here we replace ALL keys with the same value from 'special_key'
$replaced = array_fill(0, count($value), $value['special_key']);
$value = array_combine(array_keys($value), $replaced);
// Add a new key?
$value['new_key'] = 'new value';
// Get the current depth and traverse back up the tree, saving the modifications
$currentDepth = $completeIterator->getDepth();
for ($subDepth = $currentDepth; $subDepth >= 0; $subDepth--) {
// Get the current level iterator
$subIterator = $completeIterator->getSubIterator($subDepth);
// If we are on the level we want to change, use the replacements ($value) other wise set the key to the parent iterators value
$subIterator->offsetSet($subIterator->key(), ($subDepth === $currentDepth ? $value : $completeIterator->getSubIterator(($subDepth+1))->getArrayCopy()));
}
}
}
return $completeIterator->getArrayCopy();
// return:
$array = [
'test' => 'value',
'level_one' => [
'level_two' => [
'level_three' => [
'replace_this_array' => [
'special_key' => 'replacement_value',
'key_one' => 'replacement_value',
'key_two' => 'replacement_value',
'four' => 'replacement_value',
'new_key' => 'new value'
]
],
'ordinary_key' => 'value'
]
]
];