Use of 'self' in static function in subclass

php.internals

Bert Slagter

22 years ago
Hi All, I have a class and a subclass, both with a static method: <?php class Foo { static function Bar() { self::Baz(); } } class Foo2 extends Foo { static function Baz() { echo 'Baz'; } } Foo2::Bar(); ?> In this case I expect to find 'Baz' on my screen, but I get the following: "Fatal error: Call to undefined method Foo::baz() in d:\htdocs_php5\ProBase2\TRUNK\probase\libsys\test5.php on line 7". This is in PHP5 RC2. Somehow this behaviour seems logical, on the other hand I don't think it's desired. I think that 'self' should point to the current class, even if the static method resides in a parent class. Is this 'self'-behaviour intended? Bert

Stephan Schmidt

22 years ago
Hi,
> Somehow this behaviour seems logical, on the other hand I don't think > it's desired. I think that 'self' should point to the current class, > even if the static method resides in a parent class. > > Is this 'self'-behaviour intended?
Furthermore this renders the template-method pattern quite useless, so IMHO it should be changed. Stephan

Hans Lellelid

22 years ago
Bert Slagter wrote:
> Hi All, > > I have a class and a subclass, both with a static method: > > <?php > class Foo > { > static function Bar() > { > self::Baz(); > } > } > > class Foo2 extends Foo > { > static function Baz() > { > echo 'Baz'; > } > } > > Foo2::Bar(); > ?> > > In this case I expect to find 'Baz' on my screen, but I get the > following: "Fatal error: Call to undefined method Foo::baz() in > d:\htdocs_php5\ProBase2\TRUNK\probase\libsys\test5.php on line 7". > > This is in PHP5 RC2. > > Somehow this behaviour seems logical, on the other hand I don't think > it's desired. I think that 'self' should point to the current class, > even if the static method resides in a parent class.
Yeah, this probably should change to be consistent. I've been living fine with the current behavior, but considering self::*() will automatically invoke the parent class' method if none is defined in current class, then it should probably also work the other way around. My .02, Hans

Ferdinand Beyer

22 years ago
On 1 Jun 2004 at 15:21, Stephan Schmidt wrote:
> Furthermore this renders the template-method pattern quite
useless, so
> IMHO it should be changed.
He should define an abstract method Foo::Baz() here.
-- Ferdinand Beyer <fb@fbeyer.com>

Hans Lellelid

22 years ago
Ferdinand Beyer wrote:
> On 1 Jun 2004 at 15:21, Stephan Schmidt wrote: > > >>Furthermore this renders the template-method pattern quite > > useless, so > >>IMHO it should be changed. > > > He should define an abstract method Foo::Baz() here. >
Yes, I agree that design-wise that would be better -- but it will still fail w/ E_FATAL in PHP if the method is abstract ("cannot call abstract method Foo::Baz() in ...."). Hans

Bert Slagter

22 years ago
Ferdinand Beyer wrote:
> He should define an abstract method Foo::Baz() here. >
This is a minimal testcase, in my real life situation there indeed is a 'abstract static function Baz();' in Class Foo. But indeed, then a "Fatal error: Cannot call abstract method Foo::Baz() in.." arises.. Bert

Ferdinand Beyer

22 years ago
On 1 Jun 2004 at 16:19, Bert Slagter wrote:
> This is a minimal testcase, in my real life situation there indeed is a > 'abstract static function Baz();' in Class Foo. But indeed, then a > "Fatal error: Cannot call abstract method Foo::Baz() in.." arises..
OK, this is indeed a problem then.
-- Ferdinand Beyer <fb@fbeyer.com>

Timm Friebe

22 years ago
On Tue, 2004-06-01 at 15:11, Bert Slagter wrote:
> Hi All, > > I have a class and a subclass, both with a static method:
[...]
> Somehow this behaviour seems logical, on the other hand I don't think > it's desired. I think that 'self' should point to the current class, > even if the static method resides in a parent class. > > Is this 'self'-behaviour intended?
Yes: self is bound at compiletime. It would need to be changed to evaluation at runtime und would be far more useful then. This has been reported a couple of times, in slight variations: http://zend.com/lists/engine2/200307/msg00033.html http://zend.com/lists/engine2/200307/msg00036.html http://zend.com/lists/engine2/200309/msg00024.html In one of these, Marcus suggested a new keyword "this" which would behave like a run-time self, e.g: class Test { public static function getInstance() { return new this(); } } class Foo extends Test { } var_dump(Foo::getInstance()); would output "object(foo)" instead of "object(test)". I wouldn't mind chaning self in the first place, though. - Timm

Ferdinand Beyer

22 years ago
On 1 Jun 2004 at 21:13, Timm Friebe wrote:
> Yes: self is bound at compiletime. It would need to be changed to > evaluation at runtime und would be far more useful then. > > [...] > > I wouldn't mind chaning self in the first place, though.
I prefer your solution to evaluate self at runtime instead of adding a new keyword 'this'. The second one would only be confused with $this. Many people (including me) are already familiar with 'self' and expect it to refer to the class from within it is called.
-- Ferdinand Beyer <fb@fbeyer.com>

Hans Lellelid

22 years ago
Ferdinand Beyer wrote:
> On 1 Jun 2004 at 21:13, Timm Friebe wrote: > > >>Yes: self is bound at compiletime. It would need to be changed to >>evaluation at runtime und would be far more useful then. >> >>[...] >> >>I wouldn't mind chaning self in the first place, though. > > > I prefer your solution to evaluate self at runtime instead of adding a > new keyword 'this'. The second one would only be confused with > $this. Many people (including me) are already familiar with 'self' and > expect it to refer to the class from within it is called. >
Yeah +1 on self:: binding at runtime. I can't really imagine a case where you would want to refer to 'self' as the class that contains the method *and not* the overridden method in invoked class (if it exists). Binding this at runtime will introduce many new design possibilities with static classes and will also make self:: consistent with $this-> behavior for objects. Hans

Adam Bregenzer

22 years ago
On Tue, 2004-06-01 at 19:53, Hans Lellelid wrote:
> Yeah +1 on self:: binding at runtime. I can't really imagine a case > where you would want to refer to 'self' as the class that contains the > method *and not* the overridden method in invoked class (if it exists). > Binding this at runtime will introduce many new design possibilities > with static classes and will also make self:: consistent with $this-> > behavior for objects.
+1, I agree completely. I think it is critical to have a way to be able to have a static method call another static method in the same class that respects inheritance. If a developer wanted a call to not respect inheritance the class's name can be used instead of self with the same results (increased code maintenance should the class name change notwithstanding).
-- Adam Bregenzer adam@bregenzer.net http://adam.bregenzer.net/

Jevon Wright

22 years ago
It's something I noticed, too. Consider this: class A { function a() { return $this::b(); } function b() { return 1; } } class B extends A { function b() { return 2; } } If I call $b = new B(); echo $b->a(); No matter what combination of this, self, parent, ... - I could never get B's property. I was led to believe that this is actually normal for OO designs (is it? If so, ignore me). But it would be awesome if self or $this (ONLY one of them, if they currently perform the same function) actually referred to the top class - ie. B::b() in this case. Is this what this suggestion would suggest? Thanks, Jevon ----- Original Message ----- From: "Adam Bregenzer" <adam@bregenzer.net> To: "Hans Lellelid" <hans@velum.net> Cc: "Ferdinand Beyer" <fb@fbeyer.com>; "Timm Friebe" <thekid@thekid.de>; <internals@lists.php.net> Sent: Wednesday, June 02, 2004 12:26 PM Subject: Re: [PHP-DEV] Use of 'self' in static function in subclass

Andi Gutmans

22 years ago
I don't agree as I don't think static methods should be virtual. This is what $this-> exists for. Re-design...! Andi At 03:11 PM 6/1/2004 +0200, Bert Slagter wrote: