How can I use __get() to return null in multilevel object property accessing the case like this below?
For instance, this is my classes,
class property
You can can return new property instead of null
public function __get($name)
{
return (isset($this->$name)) ? $this->$name : new property();
}
Yes it is, but it's not so trivial to explain how. First understand why you run into that problem:
$value = $a->b->c;
This will first return NULL
for $a->b
. So actually you wrote:
$value = NULL->c;
So instead of NULL
on an unset item you need to return a NULL
-object (let's namne it NULLObect
) that works similar to your base class and that represents NULL
.
As you can imagine, you can not really simulate NULL
with it in PHP and PHP's language features are too limited to make this seamlessly.
However you can try to come close with the NULLObect
I've describben.
class property
{
public function __get($name)
{
isset($this->$name) || $this->$name = new NULLObject();
return $this->$name;
}
}
class NULLObject extends Property {};
Take care that this might not be exactly what you're looking for. If it does not matches your need, it's highjly likely that PHP is the wrong language you use for programming. Use some language that has better features of member overriding than PHP has.
Related Question:
Yes, I know it's been 4 years ago, but I had a similar problem this week, and while I trying to solve it, I found this thread. So, here is my solution:
class NoneWrapper
{
private $data;
public function __construct($object)
{
$this->data = $object;
}
public function __get(string $name)
{
return property_exists($this->data, $name)
? new NoneWrapper($this->data->$name)
: new None;
}
public function __call($name, $arguments)
{
if (is_object($this->data)) {
return (property_exists($this->data, $name))
? $this->data->$name
: null;
} else {
return null;
}
}
public function __invoke()
{
return $this->data;
}
}
class None
{
public function __get(string $name) {
return new None;
}
public function __call($name, $arguments)
{
return null;
}
public function __invoke()
{
return null;
}
}
$object = new NoneWrapper(
json_decode(
json_encode([
'foo' => [
'bar' => [
'first' => 1,
'second' => 2,
'third' => 3,
'fourth' => 4,
],
]
])
)
);
var_dump($object->foo->bar->baz()); // null
var_dump($object->foo->bar->third()); // 3