Doc #81436 [Com]: Unclear behaviors with __call/__callStatic/forward_static_call and LSB
[email protected] ("topfitnesscareblog at gmail dot com") Fri, 19 May 2023 06:32:18 +0000
| Newsgroups | php.doc.bugs |
|---|---|
| Message-ID | <[email protected]> |
Edit report at https://bugs.php.net/bug.php?id=81436&edit=1
ID: 81436
Comment by: topfitnesscareblog at gmail dot com
Reported by: dev98 at outlook dot de
Summary: Unclear behaviors with
__call/__callStatic/forward_static_call and LSB
Status: Open
Type: Documentation Problem
Package: Class/Object related
Operating System: Windows x64, Manjaro Linux x64
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Top Fitness Care Blog are sharing health, diet, weight loss, treatment, allergy etc. More info to visit: (https://topfitnesscareblog.com)github.com
Previous Comments:
------------------------------------------------------------------------
[2021-09-16 08:23:17] [email protected]
> Maybe the php.net documentation just needs a few additional notes regarding the
> forward_static_call and __callStatic topic, as you stated that there have been a
> few reports about that in the past.
Sure.
------------------------------------------------------------------------
[2021-09-16 07:22:50] dev98 at outlook dot de
Requinix thanks for the answers. I really appreciate your effort and time put into it. I fully understand your points.
Maybe the php.net documentation just needs a few additional notes regarding the forward_static_call and __callStatic topic, as you stated that there have been a few reports about that in the past.
------------------------------------------------------------------------
[2021-09-14 14:47:28] [email protected]
> If you replace the A::BLA code with:
> forward_static_call(array("A", "BLA"))
> I feel it should definitely call the static method BLA on A and not anything else.
Consider that "static" methods are not so much "this method only exists statically" but rather "this method can be called statically". Static-ness is more like an invocation capability than it is a requirement; you can call static methods with "$this->" just fine (though it's poor practice to do so).
https://3v4l.org/uO01h
So it's not quite correct to say "the static method BLA".
If you follow that train of thought further, a forward_static_call()ed A::BLA is very much like a regular A::BLA call. The problem that forward_static_call() solves is one that stems from the fact that PHP allows static things to be inherited down a class hierarchy [1], and that otherwise there is no way for a child class to call a parent class's static method while retaining the child's "static" information.
If that's confusing, think about what happens with object instances. $this always refers to the child-est members in the inheritance hierarchy <https://3v4l.org/H1T04>. Static members need something similar.
Before PHP 5.3 and late static bindings [2], there was no similar mechanism for static members. "self" always indicated the class where it was used. LSB changed how static members were handled internally and introduced/borrowed "static" to be like the static version of $this, ie. to refer to the child-est members.
...except there's a slight problem here because PHP needs some way to know who that so-called child is. It was already very capable of handling that with instance members because there's, you know, the instance. But there is no instance in memory when dealing with static method calls. Thus LSB's "runtime information" [3] to fill in the gap. Then forward_static_call() was created to provide users with a way of saying that a static method somewhere should be invoked, except rather than *reset* the "runtime information" like would normally happen with a static call [4], PHP should *retain and reuse* it.
I think I may have digressed a bit...
> Or asked differently: How would one call A::BLA from an object context? Is this impossible?
You mean is it possible here to trigger A's __callStatic() with $name="BLA"?
As far as I know: no, it is not currently possible to convince PHP to execute in that way.
I see bug #65466 but I feel like I've seen one or two bug reports/feature requests about the same phenomenon more recently than that. Also, a concrete use case would be helpful - especially one that can't be resolved in a more logical way than needing __callStatic.
On that note, keep in mind that __callStatic does not mean "you attempted to call a static method which did not exist". It means "you attempted to call a method which did not exist and at a time when you did not have an instance of the class on hand". Remember what I said at the beginning of this wall of text: static does not mean it's *only* static but that it *can be* invoked statically.
Personally, I don't use __callStatic at all. Too many nuances about how and when static things work.
[1] Don't care for it myself, but whether this makes sense or not is beside the point.
[2] https://www.php.net/manual/en/language.oop5.late-static-bindings.php
[3] In the LSB docs,
> This feature was named "late static bindings" with an internal perspective in
> mind. "Late binding" comes from the fact that static:: will not be resolved
> using the class where the method is defined but it will rather be computed
> using runtime information.
[4] IIRC there used to be ways to trick PHP into leaking $this or a static method's scope into unrelated code, but I believe those have all been patched/fixed/removed.
------------------------------------------------------------------------
[2021-09-14 13:31:27] nerdbeere2k at gmail dot com
I fail to understand why this works the way it does as well.
If you replace the A::BLA code with:
forward_static_call(array("A", "BLA"))
I feel it should definitely call the static method BLA on A and not anything else.
Or asked differently: How would one call A::BLA from an object context? Is this impossible?
------------------------------------------------------------------------
[2021-09-14 13:16:43] [email protected]
Of course it's only once I hit the Submit button do I see an edit to make:
> the double colon is to resolve how a method should be called
Makes more sense to say it resolves *where* a method should be called.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=81436
--
Edit this bug report at https://bugs.php.net/bug.php?id=81436&edit=1