Можно ли использовать магические методы __get и __set как для переменных-членов класса array, так и для переменных-членов класса nonarray?

#php #arrays #oop #getter-setter #magic-methods

#php #массивы #ооп #getter-setter #magic-методы

Вопрос:

В настоящее время у меня есть следующие методы __get / __set в примере класса PHP:

 class example{

    /*Member variables*/
    protected $a; 
    protected $b = array(); 

    public function __get($name){
        return $this->$name;
    }

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

}
  

Однако, в дополнение к настройке стандартных защищенных переменных, я также хотел бы иметь возможность устанавливать защищенные массивы внутри класса. Я просмотрел некоторые другие вопросы и нашел общие предложения относительно того, как просто устанавливать переменные с помощью методов __get / __set, но ничего, что позволило бы использовать эти магические методы для установки КАК массивов, так и не массивов, т. Е. Следующим образом:

 $fun = new $example(); 
$fun->a = 'yay'; 
$fun->b['coolio'] = 'yay2'; 
  

Ответ №1:

Просто, определите __get() так:

 public function amp;__get($name)
{
    return $this->$name;
}

// ...

$fun = new example();
$fun->a = 'yay';
$fun->b['coolio'] = 'yay2';
var_dump($fun);
  

Вывод:

 object(example)#1 (2) {
  ["a":protected]=>
  string(3) "yay"
  ["b":protected]=>
  array(1) {
    ["coolio"]=>
    string(4) "yay2"
  }
}
  

Соблюдайте необходимую осторожность, когда вы имеете дело со ссылками, легко ошибиться и ввести трудно отслеживаемые ошибки.

Комментарии:

1. Впечатляет, если это действительно возможно x) Но я должен сказать, как это не задокументировано? Волшебные методы PHP

2. Это кратко описано, но я хотел бы углубиться немного дальше. Если get устанавливается по ссылке, останется ли функция set идентичной предыдущей? Кроме того, учитывая риск ошибок с функцией get, которая включает ссылки, не могли бы вы предложить мне просто создать другой набор функций для работы с массивами?

3. __set() вызывается только тогда, когда свойству в целом присваивается значение, т.е. $fun->b = something_else;

4. Даже после всех этих лет я просто.не могу.поверить, что возврат по ссылке на самом деле не позволяет изменять защищенную переменную через эту ссылку, если ссылка присвоена переменной (вам нужно $a = amp;$fun->foo это включить). Хорошо сыграно, PHP, хорошо сыграно. Я что-то упускаю или это а) совершенно необоснованно, б) соответствует курсу и в) достаточная причина, чтобы всегда __get возвращать по ссылке?

5. @Jon По-видимому, согласно этому 3v4l, это должно работать таким образом… Я … сам немного удивлен 🙂