Вопрос по php – Как использовать __get () для возврата null при доступе к свойствам многоуровневого объекта?

3

Как я могу использовать __get () для возврата значения null в свойстве многоуровневого объекта, обращаясь к описанному ниже случаю?

Например, это мои занятия,

<code>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;

    }
}
</code>

Как я это использую,

<code>$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);
</code>

результат,

<code>null
</code>

но я получаю сообщение об ошибке с NULL, когда входной массивnull,

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

результат,

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

Можно ли вернуть NULL в таком сценарии?

Язык PHP не знает о многоуровневых объектах, объекты всегда являются одним узлом, который ничего не знает о его восходящем или нисходящем узле при доступе в контексте. hakre

Ваш Ответ

3   ответа
0

я знаю, что это было 4 года назад, но у меня была похожая проблема на этой неделе, и пока я пытался ее решить, я нашел эту ветку. Итак, вот мое решение:

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
1

это так, но это не так легко объяснить, как это сделать. Сначала поймите, почему вы столкнулись с этой проблемой:

$value = $a->b->c;

Это сначала вернетсяNULL за$a->b, Итак, на самом деле вы написали:

$value = NULL->c;

Так что вместоNULL на неустановленный предмет вам нужно вернутьNULL-объект (давайте назовем этоNULLObect), который работает аналогично вашему базовому классу и представляетNULL.

Как вы можете себе представить, вы не можете реально моделироватьNULL с этим в PHP и языковых особенностях PHP слишком ограничены, чтобы сделать это легко.

Однако вы можете попытаться приблизиться сNULLObect Я описал.

class property 
{

    public function __get($name)
    {
        isset($this->$name) || $this->$name = new NULLObject();
        return  $this->$name;
    }
}


class NULLObject extends Property {};

Позаботьтесь о том, чтобы это не было тем, что вы ищете. Если это не соответствует вашим потребностям, этоhighjly Скорее всего, PHP не тот язык, который вы используете для программирования. Используйте некоторый язык, который имеет лучшие возможности переопределения членов, чем PHP.

Связанный вопрос:

Working with __get() by reference
Error: User Rate Limit Exceeded laukok
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededNULLObectError: User Rate Limit Exceeded laukok
0

 public function __get($name)
    {
        return (isset($this->$name)) ? $this->$name : new property();
    }
Error: User Rate Limit Exceeded laukok

Похожие вопросы