I need a function that can set its deepest value on an instance, whether it is an object or an array.
For example, I have a function like this that I wrote and played with, but the setValue
function does not work, my silly placing of links here and there did not help me((
functions:
function setValue($name, &$initial, $value) {
// Set function not work
$names = explode('.', $name);
$lastIndex = (count($names) - 1);
$getter = (function ($name) {
if (property_exists($this, $name) === false) {
return null;
}
$value = &$this->{$name};
return $value;
})(...);
$setter = (function ($name, $value) {
if (property_exists($this, $name) === true) {
$this->{$name} = $value;
}
})(...);
$reference = &$initial;
foreach ($names as $index => $keyOrProperty) {
if (is_array($reference) === true) {
if ($lastIndex === $index) {
$reference[$keyOrProperty] = $value;
break;
}
$nextReference = &$reference[$keyOrProperty];
if ($nextReference === null) {
break;
}
$reference = &$nextReference;
continue;
}
if (is_object($reference) === true) {
if ($lastIndex === $index) {
$setter->call($reference, $keyOrProperty, $value);
break;
}
$nextReference = $getter->call($reference, $keyOrProperty);
if ($nextReference === null) {
break;
}
$reference = &$nextReference;
continue;
}
break;
}
}
function getValue($name, $initial) {
$names = explode('.', $name);
$getter = (function ($name) {
if (property_exists($this, $name) === false) {
return $this;
}
return $this->{$name};
})(...);
$accumulator = static function (mixed $curr, string $name) use ($getter): mixed {
if ($curr === null) {
return null;
}
if (is_array($curr) === true) {
return (array_key_exists($name, $curr) === true) ? $curr[$name] : null;
}
if (is_object($curr) === true) {
return $getter->call($curr, $name);
}
return $curr;
};
return array_reduce($names, $accumulator, $initial);
}
test:
class MyFoo
{
private MyBar $bar;
private array $array;
public function setBar(MyBar $bar): static
{
$this->bar = $bar;
return $this;
}
public function setArray(array $array): static
{
$this->array = $array;
return $this;
}
}
class MyBar
{
private MyFoo $foo;
private array $array;
public function setFoo(MyFoo $foo): static
{
$this->foo = $foo;
return $this;
}
public function setArray(array $array): static
{
$this->array = $array;
return $this;
}
}
$instance = (new MyFoo())
->setBar(
(new MyBar())
->setFoo(
(new MyFoo())
->setArray(
[
'myBar' => (new MyBar())
->setArray(
[
'deep' => [
'myFoo' => (new MyFoo())
->setBar(
(new MyBar())
->setArray(['test' => 'is Test'])
)
]
]
)
]
)
)
);
echo getValue('bar.foo.array.myBar.array.deep.myFoo.bar.array.test', $instance);
setValue('bar.foo.array.myBar.array.deep.myFoo.bar.array.test', $instance, 'Set Test');
echo getValue('bar.foo.array.myBar.array.deep.myFoo.bar.array.test', $instance);
Is it even possible to write such a function, or does anyone have any ideas?