为什么 ReflectionProperty->setValue() 方法没有设置属性,而是尝试设置字段?如果我需要设置属性值该怎么办?



我编写了一个简单的测试,使用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过时。

最新更新