How to use __get() to return null in multilevel object property accessing?

萝らか妹 提交于 2019-12-20 02:28:36

问题


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 
{

    public function __get($name)
    {
        return (isset($this->$name)) ? $this->$name : null;
    }
}


class objectify
{

    public function array_to_object($array = array(), $property_overloading = false)
    {
        # if $array is not an array, let's make it array with one value of former $array.
        if (!is_array($array)) $array = array($array);

        # Use property overloading to handle inaccessible properties, if overloading is set to be true.
        # Else use std object.
        if($property_overloading === true) $object = new property();
            else $object = new stdClass();

        foreach($array as $key => $value)
        {
            $key = (string) $key ;
            $object->$key = is_array($value) ? self::array_to_object($value, $property_overloading) : $value;
        }


        return $object;

    }
}

How I use it,

$object = new objectify();

$type = array(
    "category"  => "admin",
    "person"    => "unique",
    "a"         => array(
        "aa" => "xx",
        "bb"=> "yy"
    ),
    "passcode"  => false
);


$type = $object->array_to_object($type,true);
var_dump($type->a->cc);

result,

null

but I get an error message with NULL when the input array is null,

$type = null;
$type = $object->array_to_object($type,true);
var_dump($type->a->cc);

result,

Notice: Trying to get property of non-object in C:\wamp\www\test...p on line 68
NULL

Is it possible to return NULL in this kind of scenario?


回答1:


You can can return new property instead of null

 public function __get($name)
    {
        return (isset($this->$name)) ? $this->$name : new property();
    }



回答2:


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:

  • Working with __get() by reference



回答3:


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


来源:https://stackoverflow.com/questions/10462234/how-to-use-get-to-return-null-in-multilevel-object-property-accessing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!