2011-06-23 17 views
50

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 getStaticProperties() objetos de reflexión. Esto obtiene propiedades private y public static y sus valores.¿Hay alguna manera de establecer una propiedad estática privada/protegida utilizando clases de reflexión?

El problema es que no parece obtener el mismo resultado cuando trato de restaurar las propiedades con el método setStaticPropertyValue($key, $value) de los objetos de reflexión. private y protected variables no son visibles para este método como lo son para getStaticProperties(). Parece inconsistente.

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

INTENTARON

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(); 

Respuesta

65

Para acceder a las propiedades privadas/protegidos de una clase es posible que tenga que configurar la accesibilidad de esa primera clase, utilizando la reflexión. Pruebe el siguiente código:

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

Esto es bastante correcto, probablemente también quiera usar '$ refProperty-> setValue (null, 'new value');' para establecer el nuevo valor de la variable. – tplaner

+0

Gracias @evolve. No funcionaba hasta que usé setValue(). ¡Gracias! – dqhendricks

+0

@dqhendricks no hay problema, buena pregunta. – tplaner

33

Para acceder a las propiedades privadas/protegidos de una clase, utilizando la reflexión, sin la necesidad de un ReflectionObject ejemplo:

Para las 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'); 
+0

'ReflectionProperty :: setValue() espera que el parámetro 1 sea objeto, nulo dado' Tu respuesta tiene el mismo problema que tuve con @ Shamee's – ThorSummoner

+1

Esto ciertamente funciona en PHP 5.6, y la documentación sugiere que esto fue siempre cómo debería funcionar (ver: http://php.net/manual/en/reflectionproperty.setvalue.php), así que no estoy seguro de por qué no funcionó para @ThorSummoner – DanielM

Cuestiones relacionadas