php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38037 private members problem after inheritance...
Submitted: 2006-07-07 21:46 UTC Modified: 2006-07-07 22:31 UTC
Votes:19
Avg. Score:4.9 ± 0.3
Reproduced:15 of 16 (93.8%)
Same Version:14 (93.3%)
Same OS:12 (80.0%)
From: panza at zs dot lviv dot ua Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 5.* OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please — but make sure to vote on the bug!
Your email address:
MUST BE VALID
Solve the problem:
19 + 38 = ?
Subscribe to this entry?

 
 [2006-07-07 21:46 UTC] panza at zs dot lviv dot ua
Description:
------------
I have searched Bugs throughout, and found similar problems,  addressing the visibility issue, this is quite different...

During inheritance, the private members of the parent class are inheriated as well, but can only be modified by the methods defined in parent class. The methods defined in the child class can not modify these variables, but only child's own members. The problem here is, that theoretically this situation seems wrong. Once inherited, the methods should "belong" to the child, therefore even though they are defined in parent, they should modify child's members when called, No? Also in this situation, as shown in the code during var_dump of the $b variable, we can see two private "_vars" members, how can this be logical, two variables with same name belong to same namespace,yet one only accessible by it's parents methods,while other by it's own methods.

Note: I first came across this problem, while using Zend Framework and extending Zend_View class. If needed I can send source to show the importance of this.

In my opinion, the "old" parents private members should not be shown using var_dump and similar output functions to stop confussion, and the inherited methods should work with members in the child class, not parent, since they were called from child class and the logic would suguest this.

Reproduce code:
---------------
http://www.zs.lviv.ua/~panza/error.phps

Expected result:
----------------
$this belongs to B
$this belongs to B
Variable, $b->somevar, was assigned in B costructor, but the call was made to __set in parent class, A, making it defined in _vars which belongs to A. During retrive, we __get from parent is called, so we get the value we assigned
string(6) "value1"
Although, this time retriving the same variable using function defined in child class, B, we get NULL.
string(6) "value1"
This is because when inheriting a class, the private variables are inherited as well, but only access by function which were defined in the parent class. The functions that were defined in child class modify/access their own variable with the same name.

object(B)#1 (3) {
  ["_glovalvars:private"]=>
  NULL
  ["_vars:private"]=>
  array(3) {
    ["somevar"]=>
    string(6) "value1"
    ["UsingfunctionFromA"]=>
    string(14) "Set _vars in A"
    ["UsingB"]=>
    string(15) "Sets _vars in B"
  }
}

Actual result:
--------------
$this belongs to B
$this belongs to B
Variable, $b->somevar, was assigned in B costructor, but the call was made to __set in parent class, A, making it defined in _vars which belongs to A. During retrive, we __get from parent is called, so we get the value we assigned
string(6) "value1"
Although, this time retriving the same variable using function defined in child class, B, we get NULL.
NULL
This is because when inheriting a class, the private variables are inherited as well, but only access by function which were defined in the parent class. The functions that were defined in child class modify/access their own variable with the same name.

object(B)#1 (3) {
  ["_glovalvars:private"]=>
  NULL
  ["_vars:private"]=>
  array(1) {
    ["UsingB"]=>
    string(15) "Sets _vars in B"
  }
  ["_vars:private"]=>
  array(2) {
    ["somevar"]=>
    string(6) "value1"
    ["UsingfunctionFromA"]=>
    string(14) "Set _vars in A"
  }
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-07-07 21:50 UTC] tony2001@php.net
Yes. methods defined in class A are executed in context of class A.
We're working on late static binding, but currently it's not available in PHP, you have to wait until it's ready.
 [2006-07-07 22:01 UTC] panza at zs dot lviv dot ua
Just to clarify... How long untill we see this feature in action? PHP 5.1.5, PHP 5.2 or PHP. Just wondering about the timeframe, since I don't think there's any work arounds without changing the Base class?
 [2006-07-07 22:12 UTC] helly@php.net
Not in 5.2
 [2006-07-07 22:31 UTC] panza at zs dot lviv dot ua
If anyone can see a work around, preferebly "not expensive", without any modifications to the Base class I'll be very thankfull if they could email me or post it here.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 12:01:27 2024 UTC