Возможно ли инициализировать объекты частными или защищенными членами в php с помощью ассоциативного массива.
например:
class TestClass { public $_name; public $_age; public function __construct(array $params) { ?????? } } $testClass = new TestClass( array( 'name' => 'Bob', 'age' => '29', ) );
Мне было интересно, есть ли элегантное решение – возможно, реализовав один интерфейс spl или иначе?
Вы упомянули SPL. Но, не зная точных требований к цели вашего объекта, ниже приведена единственная информация, которую я могу дать …
Вы могли бы расширить свой объект, ArrayIterator
встроенный класс ArrayIterator
. Затем, не заботясь о его обработке в конструкторе (уже обработанном в родительском классе ArrayIterator
), вы можете импортировать массив в свой объект, просто так:
class testClass extends ArrayIterator { /* child '__construct' method not required */ /* rest of your code here */ } $t = new testClass(array('name' => 'asdf', 'age' => 99));
Имейте в виду, что с поведением ArrayIterator
умолчанию вы не можете позже получить доступ к любому из переданных значений массива, как это было бы с обычным объектным свойством. Вы должны получить к ним доступ, как и массив:
echo $t['name']; // 'asdf' echo $t->name; // NULL property unknown error
И, внутренне, переданный массив хранится в вашем объекте как один частный параметр storage
. В вашем случае у вас уже есть все ваши свойства объекта, предварительно определенные и добавленные с помощью подчеркивания, поэтому вам, вероятно, придется вручную зацикливать над $this
или $params
в вашем конструкторе, чтобы установить какие-либо реальные свойства объекта.
Конечно, вы могли бы переопределить все унаследованные методы ArrayIterator
вашего дочернего объекта, чтобы обрабатывать ваш случай именования специальных свойств при get
или ArrayIterator
, но это казалось бы излишним и непроизводительным, а не просто циклом над $params
/ установкой $this
любом случае в вашем конструкторе.
public function __construct(array $params) { foreach ($params as $key => $val) { if (property_exists($this, "_$key")) { $this->{"_$key"} = $val; } } }
Таким образом, просто зацикливание на $params
/ setting $this
внутри вашего конструктора, вероятно, является лучшим, самым простым решением.
foreach ($params as $key=>$value) { $key = '_'.$key; $this->$key=$value; }
См. Код онлайн для рабочей выборки здесь