如何在 PHP 8.1 中使用反射更改只读属性?

Mat*_*sen 8 php reflection php-8 php-8.1

有没有办法使用反射或其他方式来更改已设置的只读属性?

我们有时会在测试中这样做,并且我们不想避免仅出于测试目的而使用只读属性。

class Acme {
    public function __construct(
        private readonly int $changeMe,
    ) {}
}

$object= new Acme(1);
$reflectionClass = new ReflectionClass($object);
$reflectionProperty = $reflectionClass->getProperty('changeMe');
$reflectionProperty->setAccessible(true);
$reflectionProperty->setValue($object, 2);
Run Code Online (Sandbox Code Playgroud)
Fatal error: Uncaught Error: Cannot modify readonly property Acme::$changeMe
Run Code Online (Sandbox Code Playgroud)

Fat*_*ror 4

我能想到的更改readonly属性的唯一方法是反映对象而不调用其构造函数。但是,不确定它在您的特定情况下是否有用

class Acme {
    public function __construct(
        public readonly int $changeMe,
    ) {}
}

$object = new Acme(1);
$reflection = new ReflectionClass($object);
$instance = $reflection->newInstanceWithoutConstructor();
$reflectionProperty = $reflection->getProperty('changeMe');
$reflectionProperty->setValue($instance, 33);

var_dump($reflectionProperty->getValue($instance)); // 33
Run Code Online (Sandbox Code Playgroud)

https://3v4l.org/mis1l#v8.1.0

注意:我们实际上并没有“更改”属性,我们只是第一次设置它,因为没有调用构造函数。