有没有办法使用反射类设置私有/受保护的静态属性?

时间:2011-06-23 02:01:11

标签: php reflection visibility

我正在尝试为类的静态属性执行备份/恢复功能。我可以使用反射对象getStaticProperties()方法获取所有静态属性及其值的列表。这会获得privatepublic static属性及其值。

问题是我尝试使用反射对象setStaticPropertyValue($key, $value)方法恢复属性时似乎没有得到相同的结果。此方法看不到privateprotected个变量,因为它们属于getStaticProperties()。似乎不一致。

有没有办法使用反射类或任何其他方式设置私有/受保护的静态属性?

受审

class Foo {
    static public $test1 = 1;
    static protected $test2 = 2;

    public function test () {
        echo self::$test1 . '<br>';
        echo self::$test2 . '<br><br>';
    }

    public function change () {
        self::$test1 = 3;
        self::$test2 = 4;
    }
}

$test = new foo();
$test->test();

// Backup
$test2 = new ReflectionObject($test);
$backup = $test2->getStaticProperties();

$test->change();

// Restore
foreach ($backup as $key => $value) {
    $property = $test2->getProperty($key);
    $property->setAccessible(true);
    $test2->setStaticPropertyValue($key, $value);
}

$test->test();

3 个答案:

答案 0 :(得分:74)

要访问类的私有/受保护属性,我们可能需要首先使用反射设置该类的可访问性。请尝试以下代码:

$obj         = new ClassName();
$refObject   = new ReflectionObject( $obj );
$refProperty = $refObject->getProperty( 'property' );
$refProperty->setAccessible( true );
$refProperty->setValue(null, 'new value');

答案 1 :(得分:37)

使用反射访问类的私有/受保护属性,而不需要ReflectionObject实例:

对于静态属性:

<?php
$reflection = new \ReflectionProperty('ClassName', 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue(null, 'new property value');


对于非静态属性:

<?php
$instance = New SomeClassName();
$reflection = new \ReflectionProperty(get_class($instance), 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue($instance, 'new property value');

答案 2 :(得分:0)

您还可以实现类内部方法来更改对象属性访问设置,然后使用 $instanve->properyname = ..... 设置值:

public function makeAllPropertiesPublic(): void
{
    $refClass = new ReflectionClass(\get_class($this));
    $props = $refClass->getProperties();
    foreach ($props as $property) {
        $property->setAccessible(true);
    }
}