Bug #78372 [Nab->Dup]: Calling __set magic method on ReflectionProperty::setValue()
Edit report at https://bugs.php.net/bug.php?id=78372&edit=1
ID: 78372
Updated by: requinix@php.net
Reported by: i dot spyric at gmail dot com
Summary: Calling __set magic method on
ReflectionProperty::setValue()
-Status: Not a bug
+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:
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).
Previous Comments:
------------------------------------------------------------------------
[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
Thread (5 messages)