Comments (10)
It makes sense in that I understand what is happening (and will avoid calling static methods with self
from now on to avoid this type of problem), yes.
I still maintain that this is a scenario that should be more clearly documented, since the mention of self
in the docs about late static binding initially reinforced the feeling that something was wrong, where it should instead make it clear that what's happening is expected (at least from a "this is what the maintainers of PHP have decided should happen" sense, if not from the perspective of the developer using it :p)
from doc-en.
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...
from doc-en.
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
and late static binding which at best needs clearer documentation.
from doc-en.
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 self
vs static
, the former always refers to the class in which the code is written, while the latter is resolved at runtime to be the called class - the same as get_called_class. So in your first example, because self::class
was written within foo
so it will evaluate to "foo", while static::class
will evaluate to "bar" because that chain of static method calls began using bar
.
from doc-en.
That makes some sense.
I think most of my confusion is that I have trained myself to see self
to mean "the class where this code is defined", which matches how it's described in the documentation about late static binding.
You even said yourself:
For
self
vsstatic
, the former always refers to the class in which the code is written
This means that self
in the foo
class refers to the foo
class...
So with the foo
class in the issue description, I'd expect these two be identical:
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 self
, since it can produce unexpected results.
from doc-en.
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.
from doc-en.
But they're not identical when late static binding comes into play.
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.
https://3v4l.org/TRP70
self
and static
stay within the hierarchy so the LSB remains intact - it doesn't start up a new one just because you switched keywords. The difference between the two is which particular version of a method should be executed: the one defined in the code's own class, or the one defined by the LSB class.
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 static::
being equivalent to $this->
.
Also.... does the "Status: Needs Feedback" label mean you were waiting for a response from me?
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? 😉
from doc-en.
The main change that I think would clear it up for me is after this statement:
Static references to the current class like
self::
or__CLASS__
are resolved using the class in which the function belongs, as in where it was defined
Like I said before, in my initial example the above wording leads me to believe that get_called_class()
should be returning foo
, because that is the class where the self::
was defined.
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.
from doc-en.
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.
https://3v4l.org/TRP70
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:
class Four {
public static function four() {
var_dump(static::class);
}
}
class Three extends Four {
public static function three() {
var_dump(static::class);
Four::four();
}
}
class Two extends Three {
public static function two() {
var_dump(static::class);
static::three();
}
}
class One extends Two {
public static function one() {
var_dump(static::class);
self::two();
}
}
$one = new One();
$one->one();
and the output is the same:
string(3) "One"
string(3) "One"
string(3) "One"
string(4) "Four"
from doc-en.
FWIW using self::class::myMethod()
does what I originally expected self::myMethod()
to do.
from doc-en.
Related Issues (20)
- LDAP: `ldap_connect()`/`ldap_bind()`/`ldap_set_option()` is unclear
- filesize() to return size of symlink rather than the target file size HOT 13
- YetiForce CRM 7.0.1 LDAP Integration issues HOT 1
- Clarify how proc_open() handles simple filenames
- Example page in manual for Error Handling uses old/deprecated code HOT 1
- Documentation for preg_match and preg_match_all flag PREG_OFFSET_CAPTURE wrong
- uopz_compose is not listed as `deprecated` in the sidebar HOT 2
- Remove XForms documentation
- sem_get add warning about freeing variable HOT 1
- hash_algos() docs should clarify which algos are cryptographic HOT 11
- MariaDB support in documentation HOT 11
- `strcmp` falsely claims it returns a 0, 1 or -1 HOT 1
- Typo Enums HOT 1
- mismatch between array_walk(_recursive) return type in stub and documentation HOT 1
- Destructuring assignment from null does not raise warning HOT 1
- Potential deprecated list of "Experimental Extensions" HOT 1
- Ip Configuration
- . HOT 3
- Document when PHP automatically sets the $previous value in new Throwables
- .
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from doc-en.