Bug #78904 [Nab]: Side-effects for uninitialised typed property

From: Date: Wed, 04 Dec 2019 06:08:06 +0000
Subject: Bug #78904 [Nab]: Side-effects for uninitialised typed property
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-224035@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78904&edit=1 ID: 78904 Updated by: nikic@php.net Reported by: public at grik dot net Summary: Side-effects for uninitialised typed property Status: Not a bug Type: Bug Package: *General Issues PHP Version: 7.4.0 Block user comment: N Private report: N New Comment: Do you have any particular (not quite so reduced) examples where this causes problems in practice? We had some issues with __set interaction that were addressed, so possibly there is some tweak in behavior possibly here as well, it's just not clear from the bug report what the actual issue is. But generally, yes, initializing typed properties is obligatory, that's part of the point of having them. __get is called to allow some lazy initialization patterns, but shouldn't be relevant for most purposes. Is the issue here that __get is called instead of immediately throwing a "trying to access uninitialized property" error? Previous Comments: ------------------------------------------------------------------------ [2019-12-03 22:40:37] requinix@php.net Works as intended. https://wiki.php.net/rfc/typed_properties_v2 Typed properties are never initialized to a default null, unlike untyped properties. That is why $y and $z do not show up through get_object_vars: they are uninitialized. No, it cannot simply return null because (a) the properties do not have the value of null and (b) null may not even be a valid value for the property. And as happens in some other languages, accessing an uninitialized property is not allowed. As for the fatal error, * ->y triggers __get, which returns null, which is valid for the "?string" type. No error. * ->x triggers __get, which returns null, which is not valid for the "string" type. Error. ------------------------------------------------------------------------ [2019-12-03 22:24:35] public at grik dot net Description: ------------ Unitialized properties make unpredictabe side effects. In fact, unitialized property is a Schrödinger property - it both exists and does not exist at the same time. All popular frameworks use magic getters in base classes. Having __get() called for uninitialized properties makes initialization in declaration to be obligatory, or face unpredictable side effects, as it was in Pascal 30 years ago. Scripting languages were inteneded to help avoid obligatory initialization in declaration. Test script: --------------- <?php abstract class Base{ public function __get($name){echo 'magic';} } class A extends Base{ public string $x; public ?string $y; public $z; } $A = new A; var_dump(get_object_vars($A)); //array(0) {} var_dump(property_exists($A,'x'));//true $A->z; // __get is not executed $A->y; // magic - __get() is executed $A->x; //Fatal error Expected result: ---------------- array(3) { ["x"]=> NULL ["y"]=> NULL ["z"]=> NULL } bool(true) Actual result: -------------- array(1) { ["z"]=> NULL } bool(true) magicmagic Fatal error: Uncaught TypeError: Typed property A::$x must be string, null used ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78904&edit=1

« previous php.bugs (#224035) next »