Is there any way to set a private/protected static property using reflection classes?

PhpReflectionVisibility

Php Problem Overview


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 both private and public 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 and protected variables are not visible to this method as they are to getStaticProperties(). 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();

Php Solutions


Solution 1 - Php

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 - Php

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

Solution 3 - Php

You can implement also a class internal method to change the object properties access setting and then set value with $instanve->properyname = .....:

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondqhendricksView Question on Stackoverflow
Solution 1 - PhpShameerView Answer on Stackoverflow
Solution 2 - PhpMihail H.View Answer on Stackoverflow
Solution 3 - PhpIvanView Answer on Stackoverflow