get_object_vars respects scope, so the same call returns different arrays depending on where it is written.
final class Money
{
private int $cents = 4900;
public string $currency = 'GBP';
public function inside(): array
{
return get_object_vars($this);
// ['cents' => 4900, 'currency' => 'GBP']
}
}
get_object_vars($m);
// ['currency' => 'GBP'] — called from outside
The scope sensitivity is documented and is nearly always encountered as a surprise, usually in a serialiser that worked in a test written as a method on the class and returned half the fields in production. Uninitialised typed properties are omitted entirely rather than appearing as null, which is a second and independent surprise in the same function. Reflection is the predictable alternative and is what any library should use.