# Use of 'self' in static function in subclass

- Thread: https://externals.io/message/10200
- Original archive: https://news-web.php.net/php.internals/10200
- Started by Bert Slagter on 2004-06-01T13:11:29+00:00
- Messages: 12
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #10200 — Bert Slagter — 2004-06-01T13:11:29+00:00

URL: https://externals.io/message/10200#10200

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

---

## #10201 — Stephan Schmidt — 2004-06-01T13:21:48+00:00

URL: https://externals.io/message/10200#10201 · In reply to: #10200

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

---

## #10202 — Hans Lellelid — 2004-06-01T13:43:02+00:00

URL: https://externals.io/message/10200#10202 · In reply to: #10200

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

---

## #10204 — Ferdinand Beyer — 2004-06-01T14:02:43+00:00

URL: https://externals.io/message/10200#10204 · In reply to: #10200

> 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

---

## #10207 — Hans Lellelid — 2004-06-01T14:12:48+00:00

URL: https://externals.io/message/10200#10207 · In reply to: #10204

Ferdinand Beyer wrote:

> 
> 
> 
> > […]
> 
> useless, so
> 
> > […]
> 
> 
> 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

---

## #10208 — Bert Slagter — 2004-06-01T14:19:57+00:00

URL: https://externals.io/message/10200#10208 · In reply to: #10204

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

---

## #10230 — Timm Friebe — 2004-06-01T19:13:54+00:00

URL: https://externals.io/message/10200#10230 · In reply to: #10200

> 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

---

## #10231 — Ferdinand Beyer — 2004-06-01T19:47:49+00:00

URL: https://externals.io/message/10200#10231 · In reply to: #10200

> 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

---

## #10235 — Hans Lellelid — 2004-06-01T23:53:42+00:00

URL: https://externals.io/message/10200#10235 · In reply to: #10231

Ferdinand Beyer wrote:

> 
> 
> 
> > […]
> 
> 
> 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

---

## #10236 — Adam Bregenzer — 2004-06-02T00:26:25+00:00

URL: https://externals.io/message/10200#10236 · In reply to: #10235

> 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/

---

## #10237 — Jevon Wright — 2004-06-02T00:36:26+00:00

URL: https://externals.io/message/10200#10237 · In reply to: #10236

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


> 
> > […]
>
> +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/

---

## #10255 — Andi Gutmans — 2004-06-03T08:01:15+00:00

URL: https://externals.io/message/10200#10255 · In reply to: #10200

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:
>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
