¿Hay alguna manera de establecer una propiedad estática privada/protegida usando clases de reflexión?


Estoy tratando de realizar una función de copia de seguridad/restauración para las propiedades estáticas de las clases. Puedo obtener una lista de todas las propiedades estáticas y sus valores usando el método reflection objects getStaticProperties(). Esto obtiene las propiedades private y public static y sus valores.

El problema es que no parece obtener el mismo resultado al intentar restaurar las propiedades con el método reflection objects setStaticPropertyValue($key, $value). Las variables private y protected no son visibles para este método como lo son para getStaticProperties(). Parecer inconsistente.

¿Hay alguna manera de establecer una propiedad estática privada/protegida usando clases de reflexión, o de cualquier otra manera para el caso?

INTENTADO

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();
Author: Davіd, 2011-06-23

2 answers

Para acceder a las propiedades privadas/protegidas de una clase, es posible que necesitemos establecer primero la accesibilidad de esa clase, utilizando reflexión. Prueba el siguiente código:

$obj         = new ClassName();
$refObject   = new ReflectionObject( $obj );
$refProperty = $refObject->getProperty( 'property' );
$refProperty->setAccessible( true );
$refProperty->setValue(null, 'new value');
 69
Author: Shameer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-04 13:30:25

Para acceder a propiedades privadas / protegidas de una clase, usando reflexión, sin la necesidad de una instancia ReflectionObject:

Para propiedades estáticas:

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


Para propiedades no estáticas:

<?php
$instance = New SomeClassName();
$reflection = new \ReflectionProperty(get_class($instance), 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue($instance, 'new property value');
 35
Author: m-haritonov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-10 10:16:17