He conducted a series of experiments. The answer to the question depends on the version of PHP.
Minimal example
File to serialize ser_priv.php :
class MyClass{ private $id; public function __construct($id) { $this->id = $id; } } $o = new MyClass(123); file_put_contents(__DIR__ . '/data', serialize($o));
File to deserialize unser.php :
class MyClass { // Заменили на protected protected $id; public function __construct($id) { $this->id = $id; } public function test() { $prop = new ReflectionProperty('MyClass', 'id'); printf("prop is protected: %d\n", $prop->isProtected()); printf("prop has value: %d\n", $this->id); } } $data = file_get_contents(__DIR__ . '/data'); $o = unserialize($data); $o->test();
On github
results
PHP 7.3.0RC4 : The protected property is set correctly, with the same value as before.
PHP 5.6.33 : The protected property is NOT set correctly after unserialize .
If you make var_dump($o); , it will be displayed
object(MyClass)#1 (2) { ["id":protected]=> NULL ["id":"MyClass":private]=> int(123) }
var_export($o); :
MyClass::__set_state(array( 'id' => NULL, 'id' => 123, ))
"Get" 123 decent way did not work. The indecent method of var_export and parsing did not consider the result, but this is also an option.
Now we serialize the same object, but in the first case it will be private , in the second it is protected . Let's see the binary, what happened:
$ xxd data_priv 0000000: 4f3a 373a 224d 7943 6c61 7373 223a 313a O:7:"MyClass":1: 0000010: 7b73 3a31 313a 2200 4d79 436c 6173 7300 {s:11:".MyClass. 0000020: 6964 223b 693a 3132 333b 7d id";i:123;} $ xxd data_prot 0000000: 4f3a 373a 224d 7943 6c61 7373 223a 313a O:7:"MyClass":1: 0000010: 7b73 3a35 3a22 002a 0069 6422 3b69 3a31 {s:5:".*.id";i:1 0000020: 3233 3b7d 23;}
It turns out that private is stored as ".MyClass.id", and protected as ". *. Id", only binary zeroes instead of dots. Well, the length of the string is different ( s:11 and s:5 ).
The idea is to replace private with protected . I don’t want to do something universal, maybe someone will be confused. Here is the minimum option for tinkering the id .
File unser_php56.php :
class MyClass { // свойство с измененной областью видимости protected $id; } $data = file_get_contents(__DIR__ . '/data_priv'); $data = bin2hex($data); // Заменяем определение свойства $data = str_replace('31313a22004d79436c617373', '353a22002a', $data); $data = hex2bin($data); $o = unserialize($data); var_dump($o);
Result:
object(MyClass)#1 (1) { ["id":protected]=> int(123) }
__wakeup- u_mulder function$thisfor example 2 properties:id => nullandAppBundle\MyEntity id => 123- Samar