Pull to refresh

Вложенные массивы и Magic Methods

Reading time3 min
Views17K
Наверное всем известно про волшебные(магические) методы в PHP, а конкретно __get и __set методы. Однако есть неприятная особенность, если нужно изменить значение вложенного массива. Для решение этой проблемы есть простое и элегантное решение.


Рассмотри такой вот класс:
class MyClass {
    protected $data = array('some' => array('sub' => 'data'));
 
    public function __set($name, $value) {
        $this->data[$name] = $value;
    }
    public function __get($name) {
        return $this->data[$name];
    }
}


Если попытаться изменить значение sub ключа some массива $data таким вот образом:

$my = new MyClass();
 
$my->some['sub'] = 'test'; // пытаемся изменить значение
 
echo $my->some['sub']; // выведет 'data'


Вылезет Notice:
Notice: Indirect modification of overloaded property MyClass::$some has no effect


Для решения проблемы напишем ещё один класс (у меня он называется ActiveArray, так как является частю моего ActiveRecord):

class ActiveArray {
    protected $array;
 
    public function __construct($array) {
        $this->array = &$array;
    }
 
    public function __set($name, $value) {
        $this->array[$name] = $value;
    }
 
    public function __get($name) {
        if (is_array($this->array[$name]))
            return new self(&$this->array[$name]);
        else        
            return $this->array[$name];        
    }
}


И слегка модифицируем метод __get класса MyClass:
    public function __get($name) {
        if(is_array($this->data[$name]))
            return new ActiveArray(&$this->data[$name]);
        else
            return $this->data[$name];
    }


Теперь можно обращатся ко вложенным массивам таким вот образом:
$my->some->sub = 'test';
echo $my->some->sub; // выведет 'test'
 
$my->some = array('abc' => 123);
echo $my->some->abc; // выведет '123'


Спасибо за внимание!
Tags:
Hubs:
+23
Comments64

Articles

Change theme settings