我编写了一个简单的测试,使用Reflection来设置某个类实例的属性:
namespace RufanovPHPTests
{
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('RufanovPHPTestsLaboratoryMouse');
/** @var ReflectionTests $cat */
$cat = $reflectionClass->newInstance();
$nameProperty = $reflectionClass->getProperty('Name');
$nameProperty->setValue($cat, 'Felix');
$this->assertEquals('The awesome Felix', $cat->getName());
}
}
}
它失败了。。。
我有其他面向对象编程语言的经验,这些语言也有反思。因此,我从PHP期望它将设置属性值。如果你想从OOP语言为你设置属性值,它应该找到对象属性并通过调用setter方法来设置它的值,对吗?
但PHP在这里做了一些不同的事情——它试图设置FIELD值,但该值并不像预期的那样存在。为什么?如果我只知道某个属性的名称,我如何在PHP中设置它的值?
private $name;
定义,而不是由间接设置和获取该值的两个方法定义。属性类根本不知道您将这两个函数视为$name
的getter和setter。它也不在乎,它只提供对类和/或对象属性的访问。
如果您遵循一致的命名模式,您可以使用以下语法:
$cat->{'set' . $property}('Fritz');
(我认为这是有效的。如果不行,你可能必须使用call_user_method()
。)
一种完全不同的方法是为您的类实现__get()
和__set()
。使用这些,您可以拦截属性访问,这会使单独的getter和setter过时。