Is there any way to set a private/protected static property using reflection classes?
Solution 1
For accessing private/protected properties of a class we may need to set the accessibility of that class first, using reflection. Try the following code:
$obj = new ClassName();
$refObject = new ReflectionObject( $obj );
$refProperty = $refObject->getProperty( 'property' );
$refProperty->setAccessible( true );
$refProperty->setValue(null, 'new value');
Solution 2
For accessing private/protected properties of a class, using reflection, without the need for a ReflectionObject
instance:
For static properties:
<?php
$reflection = new \ReflectionProperty('ClassName', 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue(null, 'new property value');
For non-static properties:
<?php
$instance = new SomeClassName();
$reflection = new \ReflectionProperty(get_class($instance), 'propertyName');
$reflection->setAccessible(true);
$reflection->setValue($instance, 'new property value');
dqhendricks
(An unmatched left parenthesis creates an unresolved tension that will stay with you for the rest of the day.
Updated on July 09, 2021Comments
-
dqhendricks almost 3 years
I am trying to perform a backup/restore function for static properties of classes. I can get a list of all of the static properties and their values using the reflection objects
getStaticProperties()
method. This gets bothprivate
andpublic static
properties and their values.The problem is I do not seem to get the same result when trying to restore the properties with the reflection objects
setStaticPropertyValue($key, $value)
method.private
andprotected
variables are not visible to this method as they are togetStaticProperties()
. Seems inconsistent.Is there any way to set a private/protected static property using reflection classes, or any other way for that matter?
TRIED
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();
-
ThorSummoner over 9 years
ReflectionProperty::setValue() expects parameter 1 to be object, null given
, Your answer suggest I should supply a null but php complains :( -
ThorSummoner over 9 years
ReflectionProperty::setValue() expects parameter 1 to be object, null given
Your answer has the same problem as I had with @Shamee's -
Michael Moussa over 9 yearsNote that
->setValue(null, '...')
is only allowed if the property being set is a static property. If you're attempting to modify an object property, you need to provide a real instance, or PHP will complain aboutReflectionProperty::setValue() expects parameter 1 to be object, null given
. -
DanielM over 8 yearsThis certainly works in PHP 5.6, and the documentation suggests this was always how it should work (see: php.net/manual/en/reflectionproperty.setvalue.php), so not sure why it didn't work for @ThorSummoner
-
TarranJones about 3 yearsGreat answer, Just wanted to add a note that might help someone else one day, When setting private properties you must pass the class name to which the property belongs. If the property belongs to the parent class you could do
\ReflectionProperty(get_parent_class($instance), 'propertyName')
otherwise you should do\ReflectionProperty(\namespace\ParentClass::class,'propertyName')
If the private property belongs to the current class then\ReflectionProperty($instance, 'propertyName')