Bug #78372 [Dup]: Calling __set magic method on ReflectionProperty::setValue()

From: Date: Mon, 05 Aug 2019 09:18:05 +0000
Subject: Bug #78372 [Dup]: Calling __set magic method on ReflectionProperty::setValue()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-222089@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=78372&edit=1 ID: 78372 Updated by: cmb@php.net Reported by: i dot spyric at gmail dot com Summary: Calling __set magic method on ReflectionProperty::setValue() Status: Duplicate Type: Bug Package: Scripting Engine problem Operating System: Debian PHP Version: 7.4.0beta1 Block user comment: N Private report: N New Comment: See <https://wiki.php.net/rfc/typed_properties_v2#property_initialization>. Previous Comments: ------------------------------------------------------------------------ [2019-08-05 08:50:17] requinix@php.net Then really this is a duplicate: the typed properties + __set problem, this time using reflection. The awkwardness is specifically about the property being uninitialized; once set, or when specifically unset(), __get/etc. act as expected. So it's looking like a class cannot effectively use uninitialized typed properties as well as __get/etc, and that the best option will be to always initialize them with something - even if 0 or "" or false. (I myself already do this with untyped properties.) In fact this feels like it'll be such a surprise that I would say maybe typed properties *must* be initialized, in the declaration itself: private string $test = ""; I don't see this option mentioned in the RFC and I don't remember if it came up during the RFC discussion. Rationale is that every property should always end up either with some real value or as null to represent a lack of value; for the former this default won't make much of a difference since it will be overwritten, and for the latter the type should have been ?nullable and so could be implicitly initialized by PHP (to null). ------------------------------------------------------------------------ [2019-08-05 07:55:14] nikic@php.net While this is technically "expected", I do think that we may need to do something about this, though I'm not sure what. See also bug #78226. ------------------------------------------------------------------------ [2019-08-05 07:20:45] requinix@php.net The RFC states that __get will be invoked upon reading an uninitialized typed property. Logically, __set should be invoked when writing an uninitialized typed property. This behavior matches how an unset() untyped property works, even when using reflection. https://3v4l.org/Gs1XL ------------------------------------------------------------------------ [2019-08-05 07:10:32] i dot spyric at gmail dot com Description: ------------ When you use setting value via reflection on uninitialized property __set magic method will be called. If you remove type of property or set default value, __set method will not be called. Is it a bug? Because in RFC I have not seen anything about this behavior Test script: --------------- class Example { private string $test; public function __set($name, $value) { echo "$name=$value"; } } $t = new Example(); $property = new ReflectionProperty($t, 'test'); $property->setAccessible(true); $property->setValue($t, 'foo'); Expected result: ---------------- No __set is called Actual result: -------------- __set is called ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=78372&edit=1

« previous php.bugs (#222089) next »