|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-08-22 12:25 UTC] rayro at gmx dot de
Description:
------------
While public functions will be called on the extended class, private will not. If you define a "test" function in the Foo class, the function on the extended class will be called like expected. Code is self-explaining this "problem"...
Reproduce code:
---------------
abstract class Foo {
function __call($f, $a) {
return call_user_func_array(array($this, $f), $a);
}
// uncomment this: private function test() { }
}
class Bar extends Foo {
private function test($a) {
var_dump($a);
}
}
$bar = new Bar();
$bar->test('hello');
Expected result:
----------------
string(5) "hello"
Actual result:
--------------
endless loop
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 07:00:02 2025 UTC |
Addition: The following __call function will also generate an endless loop, and there will be _no output_ if you uncomment Foo::test() here: abstract class Foo { function __call($f, $a) { return $this->{$f}($a[0]); } // private function test() { } } class Bar extends Foo { private function test($a) { var_dump($a); } } $bar = new Bar(); $bar->test('hello');Spending time sorting my brain, i agree with the conclusion that the context is not the same while extending a _class_, and i have to use protected methods here, but this is an _abstract class_? It is not really intelligible for me that abstract classes gaining a context while their not instantiable, nor i'm convinced of the abstraction design over all. :/ In my opinion, the context of the abstracted class should "fully" relate to the context of the extending class. Furthermore statically definitions should render in the class scope/context, and none static calls should result in an error if called on abstracted class (as it is with class vars). The definition of (not abstracted) functions in a abstract class should ever run in the context of the extended class, so theres no lsb necessary (e.g. __CLASS__ resolves to the classname of the extended class). Surely a topic to talk about? The following abstract class predefines the static property and method, but the result should vary towards a normal class definition. Reproduce code: --------------- abstract class Foo { public static $text; public static function test() { var_dump('get_called_class(): '.get_called_class()); var_dump(static::$text); } } class Bar extends Foo { } Foo::$text = '1'; Foo::test(); Bar::test(); Bar::$text = '2'; Foo::test(); Bar::test(); Expected result: ---------------- string(23) "get_called_class(): Foo" string(1) "1" string(23) "get_called_class(): Bar" NULL string(23) "get_called_class(): Foo" string(1) "1" string(23) "get_called_class(): Bar" string(1) "2" Actual result: -------------- string(23) "get_called_class(): Foo" string(1) "1" string(23) "get_called_class(): Bar" string(1) "1" string(23) "get_called_class(): Foo" string(1) "2" string(23) "get_called_class(): Bar" string(1) "2"Ok for now, this is more a feature request than a bug i think... ^^ Just gimme a try to explain it, thanks :) i talk about how class abstraction can be extended with such nice features like the __call->private issue described in this submission. My idea was that every method/property defined not abstracted in an abstract class should be a template/pattern for the extended class, giving the full control to redefine it but acting like a default without loosing the context in the extended class. With this change it would be possible to define private methods in abstract classes that are redefineable, except for methods defined as final. All magic methods defined in the abstract class should only run in context of the extended class, since it does never make sense for me that they got context of the abstract class. With this change it will be possible to e.g. create magic methods or normal methods that "act like defined" in the extended class. to 3) on one side, it is a nice feature to build a object tree having control to the higher static properties from the class, on the other side it will create negative side effects if setting this variable in the extended class. I think that this behaviour should be removed, since it makes much more sense to talk to the parent::$static, not to the self::$static... Here too, it makes sense to allow the abstract definition of statics, so the owner is requestet to redefine the variable. Same for class constant like self::VERSION, that should be redefined in the extended class... Look at this example that uses references, where the static reference is lost, as it should work in abstraction. It is much like the last example, except the reference to a global variable here: Reproduce code: --------------- abstract class Foo { static public $test; } class Bar extends Foo { } $my_variable = 'test'; Foo::$test =& $my_variable; var_dump(Foo::$test); var_dump(Bar::$test); Bar::$test = 'baz'; var_dump(Foo::$test); var_dump(Bar::$test); Expected result: ---------------- string(4) "test" string(4) "test" string(3) "baz" string(3) "baz" Actual result: -------------- string(4) "test" NULL string(4) "test" string(3) "baz"