get_class_vars() and typed properties

php.internals

Benjamin Morel

7 years ago
Hi Internals, I just noticed the following behaviour: class A { public int $a; public ?int $b; public ?int $c = null; } $a = new A; var_export(get_object_vars($a)); var_export(get_class_vars('A')); Result: array ( 'c' => NULL, ) array ( 'a' => NULL, 'b' => NULL, 'c' => NULL, ) Is this discrepancy expected? IMO get_object_vars() does the right thing and does not include uninitialized properties in the result array. OTOH, get_class_vars() returns null when the property is uninitialized, which I think is confusing (especially when null is not a valid value for the property), and I feel like this does not respect the documented contract: "get_class_vars — Get the default properties of the class" when null is *not* the default value. I did not file a bug yet as I wanted to gather some feedback first. Thank you. — Benjamin

Nicolas Grekas

7 years ago
Le dim. 18 août 2019 à 11:59, Benjamin Morel <benjamin.morel@gmail.com> a écrit :
> Hi Internals, I just noticed the following behaviour: > > class A { > public int $a; > public ?int $b; > public ?int $c = null; > } > > $a = new A; > > var_export(get_object_vars($a)); > var_export(get_class_vars('A')); > > Result: > > array ( > 'c' => NULL, > ) > array ( > 'a' => NULL, > 'b' => NULL, > 'c' => NULL, > ) > > Is this discrepancy expected? IMO get_object_vars() does the right thing > and does not include uninitialized properties in the result array. > > OTOH, get_class_vars() returns null when the property is uninitialized, > which I think is confusing (especially when null is not a valid value for > the property), and I feel like this does not respect the documented > contract: "get_class_vars — Get the default properties of the class" when > null is *not* the default value. > > I did not file a bug yet as I wanted to gather some feedback first. > Thank you. > > — Benjamin >
See https://bugs.php.net/78319 get_class_var() does the most useful thing, thus the correct one to me and the use cases I have. Nicolas

Rowan Collins

7 years ago
On 18 August 2019 11:14:52 BST, Nicolas Grekas <nicolas.grekas@gmail.com> wrote:
>Le dim. 18 août 2019 à 11:59, Benjamin Morel <benjamin.morel@gmail.com> >a >écrit : > >> Hi Internals, I just noticed the following behaviour: >> >> class A { >> public int $a; >> public ?int $b; >> public ?int $c = null; >> } >> >> $a = new A; >> >> var_export(get_object_vars($a)); >> var_export(get_class_vars('A')); >> >> Result: >> >> array ( >> 'c' => NULL, >> ) >> array ( >> 'a' => NULL, >> 'b' => NULL, >> 'c' => NULL, >> )
>See https://bugs.php.net/78319 >get_class_var() does the most useful thing, thus the correct one to me >and >the use cases I have.
This is a nice example of something I said when typed properties were being added: "uninitialised" is a new special state, distinct from "non-existent" and "null". As such, a non-nullable typed property without default value is impossible to represent accurately without having a representation of that state. One rather ugly possiblity in this case would be to have the values returned be "uninitialized", so that accessing the array keys was valid, but accessing the values gave an Unitialized Value Error. That would be pretty horrible for backwards compatibility, though, particularly for get_class_properties, where there's no chance for the constructor to run and set up a real value. Regards,
-- Rowan Collins [IMSoP]