The title may seem a bit silly but I'm totally serious with this. Today at work I came across a weird PHP behaviour which I could not explain. Luckily this behaviour is fixed in PHP 7.4, so it seems that someone stumbled upon that, too.
I made a small example to illustrate what went wrong:
<?php
class A {
private $a = 'This is $a from A';
public $b = 'This is $b from A';
public function __sleep(): array
{
var_dump(array_keys(get_object_vars($this)));
return [];
}
}
class B extends A
{
public $a = 'This is $a from B';
}
$b = new B;
serialize($b);
Run this code here: https://3v4l.org/DBt3o
Heres a bit explanation of what is going on here. We have to classes A and B which both share a property $a
. Careful readers noticed, that the property $a
has two different visibilities (public, private). Nothing fancy so far. The magic happens in the __sleep
method which gets magically called when we serialize
our instance. We want to have all object variables which we get with get_object_vars
reduce this to only the keys with array_keys
and output everything with var_dump
.
I would expect something like this (this happens since PHP 7.4 and is my expected output):
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "a"
}
But what I get is this:
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "a"
}
How could it be, that PHP delivers an array with two completely identical keys? Who is able to explain what happens here internally because in plain PHP I'm not able to generate an array with two completely identical keys? Or do I miss something obvious here?
My coworkers did not want to believe me at first but none of them had a good explanation of this after they understood what is happening here.
I really would love to see a good explanation.
var_dump(array_keys((array)$this));
– Dysentery