#19376 [Bgs]: Class inheritance problem

From: Date: Fri, 13 Sep 2002 04:11:42 +0000
Subject: #19376 [Bgs]: Class inheritance problem
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-19285@lists.php.net to get a copy of this message
ID: 19376 User updated by: shamim@poetryunlimited.com Reported By: shamim@poetryunlimited.com Status: Bogus Bug Type: Scripting Engine problem Operating System: Linux/Windows NT 4 PHP Version: 4.2.2 New Comment: Thank you for explaining to me that I did not explain my problem clearly. My question was rhetorical. Having been a systems engineer for the past 15 years, I know that this is an error. I was merely trying to be polite and draw your attention to it. I do not appreciate the unwarranted brush off, nor do I appreciate being told that this was a support request - I don't want to know how to do something. I want something fixed. Thanks. Hopefully you can correct this or alert Zeev that there is a problem in calling static methods from within a class instance when that static method contains the original class as part of its hierarchy. It allows the $this context to be passed from an object to a static method and back, violating class scoping. Please see the other bug report for a more clearer example. Shamim Islam BA BSc P.S. I will be posting this as many places as I can find a forum until someone understands that class scoping is being violated willy nilly. Previous Comments: ------------------------------------------------------------------------ [2002-09-12 18:15:37] alan_k@php.net Sorry, but the bug system is not the appropriate forum for asking support questions. Your problem does not imply a bug in PHP itself. For a list of more appropriate places to ask for help using PHP, please visit http://www.php.net/support.php Thank you for your interest in PHP. I cant see any unexpected behaviour here, - however it would help *alot* if you made a shorter example... ------------------------------------------------------------------------ [2002-09-12 13:07:33] shamim@poetryunlimited.com when an object of type test3 calls test3::showMe is the only time this chain should function as displayed, I believe. Thanks. ------------------------------------------------------------------------ [2002-09-12 13:05:53] shamim@poetryunlimited.com Should I be able to do the following? In the example below, class test1 is a base class for test2 which is a base class for test3. In an object of type test1, if I call the class method test3::showMe, I would expect the class method test3::showMe would be called. This class method (not member function) would would have no class context ($this), since objects of type test1 do not have a member function test3::showMe. This call should therefore fail at the debug call. Instead, the call traverses up to test3, and the recursive parent::showMe calls reverse the traversal back to the class test1, even though class test1 has no knowledge of class test3 or class test2. Or so it should be. And for some reason the $this variable exists at every level. Even though objects of type test1 do not have any test3 or test2 object contexts. I think the polymorphism is broken. Thanks. Code follows. =========================================================== <?php Header("Content-Control: no-cache"); Header("Pragma: no-cache"); function debug(&$obj,$msg) { echo "$msg<br><pre>";var_dump($obj);echo "</pre><hr>\n"; } class test1 { var $a; function test1() {$this->a=0;debug($this,"test1->new");} function setA() {$this->a+=1;debug($this,"test1->setA");} function display() {debug($this,"test1->display");echo $this->a."<br>\n";} function callMe() {debug($this,"test1->callMe");test3::showMe();} function showMe() {debug($this,"test1->showMe");$this->display();} } class test2 extends test1 { function test2() {debug($this,"test2->new");$p=get_parent_class($this);parent::$p();} function display() {debug($this,"test2->display");parent::display();} function showMe() {debug($this,"test2->showMe");parent::showMe();} } class test3 extends test2 { function test3() {debug($this,"test3->new");$p=get_parent_class($this);parent::$p();} function display() {debug($this,"test3->display");parent::display();} function showMe() {debug($this,"test3->showMe");parent::showMe();} } $b=new test2(); $b->setA(); $c=new test1(); $c->setA(); $a=new test1(); $a->showMe(); $a->callMe(); $a->setA(); $a->showMe(); $a->callMe(); $a->setA(); $a->showMe(); $a->callMe(); $a=new test2; $a->showMe(); $a->callMe(); $a->setA(); $a->showMe(); $a->callMe(); $a->setA(); $a->showMe(); $a->callMe(); /* Results: test2->new object(test2)(1) { ["a"]=> NULL } -------------------------------------------------------------------------------- test1->new object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->setA object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->new object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->setA object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->new object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- 0 test1->callMe object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test3->showMe object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test2->showMe object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- 0 test1->setA object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- 1 test1->callMe object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test3->showMe object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test2->showMe object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- 1 test1->setA object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- 2 test1->callMe object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test3->showMe object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test2->showMe object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->showMe object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->display object(test1)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- 2 test2->new object(test2)(1) { ["a"]=> NULL } -------------------------------------------------------------------------------- test1->new object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- 0 test1->callMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test3->showMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(0) } -------------------------------------------------------------------------------- 0 test1->setA object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- 1 test1->callMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test3->showMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(1) } -------------------------------------------------------------------------------- 1 test1->setA object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- 2 test1->callMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test3->showMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test2->showMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->showMe object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test2->display object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- test1->display object(test2)(1) { ["a"]=> int(2) } -------------------------------------------------------------------------------- */ ?> ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=19376&edit=1

« previous php.bugs (#19285) next »