function recursive($arg, $func, $stack = [])
{
if ($stack) {
foreach ($stack as $node) {
if ($arg === $node) {
return $arg;
}
}
}
switch (gettype($arg)) {
case 'object':
$ref = new ReflectionClass($arg);
if ($ref->iscloneable()) {
$arg = clone $arg;
$cast = is_a($arg, 'IteratorAggregate') ? iterator_to_array($arg) : get_object_vars($arg);
foreach ($cast as $key => $val) {
$arg->{$key} = $this->recursive($val, $func, array_merge($stack, [$arg]));
}
}
return $arg;
case 'array':
$copy = [];
foreach ($arg as $key => $val) {
$copy[$key] = $this->recursive($val, $func, array_merge($stack, [$arg]));
}
return $copy;
}
return $func($arg);
}