Я написал простой тест, который использует Reflection, чтобы установить свойство некоторого экземпляра класса:
namespace Rufanov\PHP\Tests
{
class LaboratoryMouse
{
/** @var string */
private $name;
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = 'The awesome ' . $name;
}
}
class ReflectionTests extends \PHPUnit_Framework_TestCase
{
public function testSetValue()
{
$reflectionClass = new \ReflectionClass('Rufanov\PHP\Tests\LaboratoryMouse');
/** @var ReflectionTests $cat */
$cat = $reflectionClass->newInstance();
$nameProperty = $reflectionClass->getProperty('Name');
$nameProperty->setValue($cat, 'Felix');
$this->assertEquals('The awesome Felix', $cat->getName());
}
}
}
Это не удается …
У меня есть опыт работы с другими объектно-ориентированными языками программирования, которые также имеют отражение. И поэтому я ожидал от PHP, что он установит значение свойства. Если вы хотите, чтобы из языка ООП было установлено значение свойства для вас, он должен найти свойство объекта и установить его значение, вызвав метод setter, верно?
Но PHP делает здесь что-то другое — он пытается установить значение FIELD, которое не существует, как ожидалось. Зачем??? Как я могу установить значение какого-либо свойства в PHP, если я знаю только его имя?
Свойство определяется private $name;
а не двумя методами, которые косвенно устанавливают и получают это значение. Класс свойства просто не знает, что вы Рассмотрим эти две функции геттеры и сеттеры для $name
, Это тоже не волнует, оно просто обеспечивает доступ к свойствам класса и / или объекта.
Если вы следуете последовательной схеме именования, вы можете использовать следующий синтаксис:
$cat->{'set' . $property}('Fritz');
(Я думаю, что это работает. Если нет, возможно, вам придется call_user_method()
.)
Совершенно другой подход заключается в реализации __get()
а также __set()
для вашего класса. Используя их, вы можете перехватить доступ к свойству, что делает отдельные методы получения и установки устаревшими.
Других решений пока нет …