перегрузка — изменение элемента массива PHP с помощью магических методов (__get и __set)

У меня есть следующий класс:

/**
* @property int $barMagic
*/
class Foo
{
public $barNormal;

private $attributes = [];

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

public function __set($name, $value)
{
$this->attributes[$name] = $value;
}
}

Как видите, публичное свойство $ barMagic не определено явно, к нему можно получить доступ с помощью магических методов.

При установке, а затем изменении элемента массива в обычном атрибуте он работает нормально:

$foo = new Foo();
$foo->barNormal = ['baz' => 1];
echo $foo->barNormal['baz'];
$foo->barNormal['baz'] = 2;
echo ',' . $foo->barNormal['baz'];

Он выводит «1,2», как и предполагалось.

Но при использовании магического свойства оно не:

$foo = new Foo();
$foo->barMagic = ['baz' => 1];
echo $foo->barMagic['baz'];
$foo->barMagic['baz'] = 2;
echo ',' . $foo->barMagic['baz'];

Он выводит «1,1»!

Есть ли способ в PHP для доступа к элементам массива в магических свойствах так же, как обычные?

Интерфейс ArrayAccess, кажется, имеет дело с доступом к массиву на один уровень выше, чем мне нужно.

1

Решение

Реальный ответ хитрый и включает в себя некоторые ошибки / несоответствия в движке PHP. Как предложили комментаторы, я добавил&»(возврат по ссылке) перед символом __get (). Итак, новый код:

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

но это дает

Notice: Only variable references should be returned by reference in ....

Я должен был изменить это на

public function &__get($name) {
if (isset($this->attributes[$name])) {
return $this->attributes[$name];
} else {
return null;
}
}

и теперь это работает. Обратите внимание, что два фрагмента должны быть полностью эквивалентны, но это не так. Спасибо всем за вклад, вы взяли меня на полпути туда.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]