-
Notifications
You must be signed in to change notification settings - Fork 769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
self
doesn't work as expected in combination with late static binding
#3293
Comments
I've just had this pointed out to me which increases my confusion: class foo {
static public function getclass() {
var_dump(self::class);
}
static public function test() {
static::getclass();
}
}
class bar extends foo {}
// will output "foo", not "bar"
bar::test(); class foo {
static public function getclass() {
var_dump(static::class);
}
static public function test() {
self::getclass();
}
}
class bar extends foo {}
// will output "bar", not "foo"
bar::test(); There's definitely something very unexpected going on with the relationship between |
self
is synonymous with static
when used upstream of get_called_class()
self
doesn't work as expected in combination with late static binding
get_called_class is working as intended: it was created before LSB was implemented, and it was that era's solution to the "how do I know what class this static method was called on?" problem. So it is supposed to return the name of the class that was first called. For |
That makes some sense.
This means that So with the static public function test() {
self::getclass();
} static public function test() {
foo::getclass();
} But they're not identical when late static binding comes into play. It sounds like that's intended - so my recommendation is that the documentation for late static binding makes this scenario explicitly clear. I'd go so far as to recommend it discourage calling static methods with |
Also.... does the "Status: Needs Feedback" label mean you were waiting for a response from me? If so, in future could you please explicitly ask for me (or whoever you're waiting on) to respond? "needs feedback" could mean (and I assumed it did mean, until the label changed again) that you're waiting for feedback from additional maintainers. I almost didn't respond at all. |
LSB kicks in when the first static method call to a class hierarchy is made, and it stays the same while you remain within that hierarchy. If you go outside the hierarchy, a new layer of LSB starts.
In other words, it's the same kind of inheritance that has always been available to class instances, with LSB being equivalent to the concept of a class instance, and
It means that I was confident you were going to reply, even if I didn't explicitly write a "So does that make sense?" at the end. And also that I didn't want to leave the issue as "needing triage" (it's not a bug), nor did I want to close it (maybe there is a bug and I don't see it). So does that make sense? 😉 |
It makes sense in that I understand what is happening (and will avoid calling static methods with I still maintain that this is a scenario that should be more clearly documented, since the mention of |
I'll move this over to the docs repo, but it would be very helpful if you could think of what kinds of changes that would like to see - what changes would have helped you if you had been able to read them earlier. Because it can be quite hard for people who are familiar with the subject matter to write good documentation for people who aren't as familiar with it... |
The main change that I think would clear it up for me is after this statement:
Like I said before, in my initial example the above wording leads me to believe that The Limitations of self:: section should ideally explicitly give an example like those in this issue with an explanation about what is actually happening there, since the behaviour noted in this issue seems to contradict what's said in that section currently. |
I slightly modified your example and the new LSB layer is started even remaining inside the same hierarchy. It is the explicit class call that triggers it regardless:
and the output is the same:
|
FWIW using |
Description
The following code:
Resulted in this output:
But I expected this output instead:
Additional context
In the docs about late static binding it says
This leads me to believe that
get_called_class()
should be returningfoo
, because that is the class where theself::
was defined, andget_called_class()
is called downstream from that.It's possible that everything's working as it's supposed to, but in that case I believe the documentation for late static binding needs to be updated to include this edge case as it's extremely unintuitive - it feels like
self
is just a synonym forstatic
in this scenario.PHP Version
PHP 8.1.27
Operating System
No response
The text was updated successfully, but these errors were encountered: