|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78372 Calling __set magic method on ReflectionProperty::setValue()
Submitted: 2019-08-05 07:10 UTC Modified: 2019-08-05 09:18 UTC
From: i dot spyric at gmail dot com Assigned:
Status: Duplicate Package: Scripting Engine problem
PHP Version: 7.4.0beta1 OS: Debian
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Bug Type:
From: i dot spyric at gmail dot com
New email:
PHP Version: OS:


 [2019-08-05 07:10 UTC] i dot spyric at gmail dot com
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->setValue($t, 'foo');

Expected result:
No __set is called

Actual result:
__set is called


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-08-05 07:20 UTC]
-Status: Open +Status: Not a bug
 [2019-08-05 07:20 UTC]
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.
 [2019-08-05 07:55 UTC]
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 08:50 UTC]
-Status: Not a bug +Status: Duplicate
 [2019-08-05 08:50 UTC]
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).
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jul 14 05:01:30 2024 UTC