php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #30934 Special keyword 'self' inherited in child classes
Submitted: 2004-11-29 22:02 UTC Modified: 2005-04-27 18:59 UTC
Votes:60
Avg. Score:4.9 ± 0.3
Reproduced:56 of 57 (98.2%)
Same Version:11 (19.6%)
Same OS:9 (16.1%)
From: jbs at fromru dot com Assigned: andi
Status: Not a bug Package: Feature/Change Request
PHP Version: 5.* OS: *
Private report: No CVE-ID:
 [2004-11-29 22:02 UTC] jbs at fromru dot com
Description:
------------
Special keyword 'self' represents the parent class instead of the child class when it is used in an inherited method of the parent class.

Reproduce code:
---------------
class Foo {
	const NAME = 'Foo';
	static public function display() {
		echo self::NAME;
	}
	static public function getInstance() {
		$instance = new self;
		return $instance;
	}
}

class Child extends Foo {
	const NAME = 'Child';
}

echo('Class constant: ');
Child::display();
echo('<BR>Object class: ');
echo(get_class(Child::getInstance()));

Expected result:
----------------
Class constant: Child
Object class: Child

Actual result:
--------------
Class constant: Foo
Object class: Foo

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-01-17 13:33 UTC] Jason at amp-design dot net
I agree, this is damn annoying. 

However, I'm sure the PHP team will come back saying "Sorry this is not a bug, it's an undocumented feature". I think this because I remember reading somewhere the ZE2 deals with constants on compile time, and therefore any references to self inside a class will point to the the class name that the reference to self points to. Ideally, if a class is extended, methods should be checked to see if the parent references self, and this should then check if the item inside self is referenced in the current class, or the parent class and adapt accordingly.

It would be so nice if this can be fixed, but I have a nasty felling people have to live with this :(
 [2005-01-17 13:47 UTC] Jason at amp-design dot net
What is also most annoying is this doesn't just affect constants, it affects anything that can be static, that is constants, class members, and methods. This looks like a rather design descision that PHP people did (I guess initially it seemed good from a speed POV).
 [2005-04-11 13:50 UTC] jbs at fromru dot com
I've noticed some similar reports. For example, the one at http://bugs.php.net/bug.php?id=30235.

Here is a quote:
>
> Sorry, you have a complete wrong idea og OO programming.
>
> Static methods are bound/resolved at compile time.
> That is the compiler can replace self with the current
> class.
>

So, it appears as it is a limitation of the compiler and the entire object model.

I think such behavior makes inheritance of static methods useless because even if a static method is inherited, it still functions as in the class where it was declared. Moreover, inherited static methods are using the static properties which were declared in the parent class but not the inherited one.

So, in my opinion "self" keyword should be replaced with the name of the inherited class during compiling. Or at least a new magic keyword should be added and named like "this", for example.
 [2005-04-12 13:28 UTC] lsmith@php.net
I think this really needs to be addressed. For example the php manual features a sample singleton implementation:
http://www.php.net/manual/en/language.oop5.patterns.php

Now how would one go about making it possible to extend the "Example" class without having to cut and paste the singleton() method to this extended class (one would probably also need to the instance property to hold an array of instances keyed be the class name)? Not exactly in the spirit of OOP imho.

It seems to me the best solution to retain this "speed optimization" of resolving these things at compile time is to copy the implementations of static items over to classes that extend that class before this evaluation is done. Just a thought from an outside perspective, dunno if this is feasible however in the ZE2 implementation.
 [2005-04-25 06:24 UTC] php-bugs at foomatic dot net
Does anyone whats happening with this bug? Is it going to be fixed or are the PHP devs just ignoring it?

Unless this is fixed (or a suitable workaround is added) I cannot put common code that refers to static variables or methods in a base class, resulting in significant code duplication. This is a huge issue, and is a perfect example  of why PHP is regarded with contempt in many circles.

My choices at the moment are to either continue hacking around it and clean up once it's been fixed, or rewrite a significant amount of legacy code in a real language. Given the rating of this bug, it looks like I'm not the only one.
 [2005-04-25 07:49 UTC] helly@php.net
First 'self' is bound at compile time (that's the way OOP works).

Second what you want is something like 'called_class'. Assume you have a static private member in your base class and a static function and your derived class does not overload that function. If now your static function is called with the derived class and 'self' would be changed to the requested behavior php won't be able to access the property. Thus you want an additional info maybe called 'used_class'.

Third to allow what you need a major change is needed that would slow down php - every part of php code execution. And that will take a while.
 [2005-04-25 10:39 UTC] php-bugs at foomatic dot net
> First 'self' is bound at compile time (that's the way OOP works).

Thats how Java works. Not All OO Languages do. PHP is a dynamic language, and shouldn't really suffer a significant performance hit by binding at run time (Especially considering it's still compiled, thus bound, for every single request anyway). 

> what you want is something like 'called_class'

As long as it's bound at runtime, I don't particuarly care what it's called. :-).
 [2005-04-25 21:14 UTC] helly@php.net
>> First 'self' is bound at compile time (that's the way
>> OOP works).
>Thats how Java works. Not All OO Languages do. PHP is a 
>dynamic language

It is not really a matter of performance here. It is just a different model of acting. And it is the way static works correct. If you read the example outline, you'll find out that it cannot work in a different way. The only thing one can do here is to eventually add what you want somehow.
 [2005-04-27 18:59 UTC] andi@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

This is expected behavior. self:: binds statically to its class (to the best of my knowledge other languages like C++ don't support this either as they require to explicitly use the class name). There are actually advantages also to this approach as they allow you to protect and encapsulate functinality.

 [2011-02-04 19:50 UTC] tim at gurka dot se
The problem in the original comment could be avoided by using $this instead of self.
 [2012-05-09 10:01 UTC] jeff at goblinoid dot co dot uk
$this doesn't work for static methods, using static:: instead of self:: will cause 
the binding to be done at runtime, and work as required. 
http://php.net/manual/en/language.oop5.late-static-bindings.php
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Mon Apr 21 12:02:07 2014 UTC