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

前端 未结 3 1560
北恋
北恋 2021-01-21 02:31

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          


        
相关标签:
3条回答
  • 2021-01-21 02:51

    You can can return new property instead of null

     public function __get($name)
        {
            return (isset($this->$name)) ? $this->$name : new property();
        }
    
    0 讨论(0)
  • 2021-01-21 03:10

    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
    0 讨论(0)
  • 2021-01-21 03:11

    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
    
    0 讨论(0)
提交回复
热议问题