I came to the conclusion that PHP is the programing language with the weirdest features. After the variable variables mess, that allows to you to name your variables stuff like !@#$%^&*()_+= and not be able to use them directly, I thought I saw everything. But no, yesterday I’ve bumped in another strange PHP feature. An even stranger feature.
Take a look at the code below:
class Example { public function dynamicMethod($string) { // calls method baz() of the same class // class Example *does not have* a baz() method $this->baz($string); } } class Foo { public function bar() { // a dynamic method called statically // no Example object is being instantiated Example::dynamicMethod('whatever'); } public function baz($string) { echo 'Method baz() called with param "' . $string . '"' . PHP_EOL; } } $foo = new Foo(); $foo->bar();
What do you think the code will do? Yield an exception? A syntax error? Work? Well, strangely enough, it works:
Tudor-Barbus-MacBook% php blog-example.php Method baz() called with param "whatever"
…and it seems that this feature is here to stay and be supported in the future, since I’m using the new PHP 5.3 version:
Tudor-Barbus-MacBook% php -v PHP 5.3.1 (cli) (built: Feb 11 2010 02:32:22) Copyright (c) 1997-2009 The PHP Group Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies
I wonder how this can be useful to somebody.
Interesting, is this an unexpected result of late static binding?
But this example is not implemented in the context of static inheritance and late static binding resolution would stop at a fully resolved static call.
Hmmm!
Feels a little like javascript, when you execute a function in a different context via call/apply.
@Andy Roberts Call me old fashioned, but if you call a method statically you shouldn’t have the $this pointer in its body. And it should be declared as “static” in the first place. Anyway, this is weird! I can’t imagine any scenario in which this would be useful.
@Siderite Yes, it looks like a closure. But a weird closure that doesn’t bring anything useful….
You should enable stricts mode, so that you get a warning for calling a non-static method in a static context. I’m pretty sure this behaviour remained in the language because the internal devs are freaks about not breaking the API even between major versions.
Maybe you should fill a bug report
It’s too well supported to be a bug…
It’s not a bug, it’s just a remnant of the PHP 4 era when there was no explicit declaration for static methods. You simply called it statically and expect a runtime error if someone use $this inside that method.
But it doesn’t throw a runtime error. It substitutes $this with the caller object. Weird…
And PHP 4 died out like 4 years ago…let’s move on people
As a counter example, think about parent::some_method(). You use the static resolution operator there too.
Either way, really strange.
What do you mean by “It’s too well supported to be a bug…” ?
BTW, you should style the blockquotes in your comments.
@scribu I mean that this is obviously by design…
Wow, this is weird, but I can imagine an excellent use, which is an implementation of multiple inheritance.
Interesting, that might work…