php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79435 property assignment via call_user_func is inconsistent
Submitted: 2020-03-30 15:55 UTC Modified: 2020-03-30 21:07 UTC
From: ikarol at gomel dot iba dot by Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.2.29 OS: Windows
Private report: No CVE-ID: None
 [2020-03-30 15:55 UTC] ikarol at gomel dot iba dot by
Description:
------------
Hi,

so if property assignment is done through call_user_func, it will only work for the first call, but will fail for all next(see var_dump output in the example).

Also, if I would assign through dynamic method name call ($this->{$methodName}($prop)), it will work fine.

Test script:
---------------
https://3v4l.org/ta03s

Expected result:
----------------
All instances of A class should have defined(not-null)C properties

Actual result:
--------------
Only the first instance of A class has it defined, while other do not.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-03-30 18:23 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2020-03-30 18:23 UTC] requinix@php.net
$testMap is initialized using the setC/setD methods on $this, which is $a1 at that time.
 [2020-03-30 19:03 UTC] ikarol at gomel dot iba dot by
So it appears that $this is considered a variable rather than being resolved dynamically as a reference to the current calling object in a context of local static variable. 
In my opinion this is not a straightforward behaviour. So $this either needs to be fixed(dynamic resolution), or this(behaviour) should be documented.
 [2020-03-30 19:17 UTC] requinix@php.net
> So it appears that $this is considered a variable
As indicated by the $, yes.

> rather than being resolved dynamically as a reference to the current calling
> object in a context of local static variable
How did you get that impression in the first place? If the documentation suggested so, that needs to be fixed.
 [2020-03-30 19:51 UTC] ikarol at gomel dot iba dot by
According to the docs(https://www.php.net/manual/en/language.oop5.basic.php), $this is a reference to the calling object. Though, there is a mention of a different behaviour for the static context, I'm sure it's only related to static(methods and properties), which is a different thing.
Looking at the docs for static variables(https://www.php.net/manual/en/language.variables.scope.php#language.variables.scope.static), there is no mention of how $this is treated. As it only mentions that variables are saved by reference, I think it will be reasonable for someone to expect a special treatment for $this(considering it's not an ordinary variable, but pseudo-variable)
 [2020-03-30 20:42 UTC] requinix@php.net
> $this is a reference to the calling object
Correct. But it sounds like you're giving $this some sort of magical behavior that doesn't exist... well, anywhere else.

Once evaluated, meaning when the code containing the "$this" is executed, it doesn't somehow change its value when used in other places. If you pass it to a global function, the function won't error because $this is invalid outside of a class. If you return it to some caller outside of the class, the value won't error because the object it was in is now out of scope. And if you try to use the value in some other class, you definitely won't get the "$this" of the second class.

$a = 1;
$b = $a;
$a = 2;
echo $b;

Obviously 1, right? Because $b is not "the $a variable". It's whatever the $a variable was at the moment it was evaluated.

Same for $this and $testMap. When $a2 or $a3 look at the callback in $testMap, they don't get "the $this variable", they get whatever the $this variable was at the moment it was evaluated.


As for your code, check out https://3v4l.org/Hm6kS
 [2020-03-30 21:07 UTC] ikarol at gomel dot iba dot by
Thanks for the suggestion, I was planning to use this, but it appears that variable function call is a bit faster(according to call_user_func comments), so I went with that.

As for $this, I'm only following documentation where it says that it($this) will be pointing to the current calling object(therefore I assume that interpreter does some automatic magic assignment for $this each time a method is called from object context)
Except for when the method is being called from static context, then $this doesn't exist at all.
Also $this cannot be manually assigned with a custom value, which is not what one would expect from ordinary variable.

In our case, $this obviously contradicts to logic in docs. If you feel that this is a correct behaviour, maybe it will be nice to add this edge case to docs as one more example when $this wouldn't point to the calling object.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 04:01:38 2024 UTC