the PHP manual says
. Members declared protected can be accessed only within the class itself and by inherited and parent classes.Members declared as private may only be accessed by the class that defines the member.
This actually works. That is if I declare something protected or private, it can not be accessed from an instance (ala $a->prop; ). And when I declare something as private it can only be withing the class itself and , theoretically and functionally , is not passed on to any extensions of the root class. In practice this seems to work: if I declare $prop as private $this->prop will not work in a child class ( unless I declare another private $prop within that child class).
Ok by now you are saying well if you are going to do that then why not make $prop protected instead of private? Actually i usually do, although sometimes it seems if I have many nested classes and I just want a couple of them tho have access to $prop that it is logical to make $prop private so that it is not inherited by child classes. again this works, functionaly.
My question is about something I noticed via var_dumps of objects.
class Test1{
public $tesVar = 'Veronica';
public $hold = array();
protected $name = '';
public $another= 'other';
private $births = 'Test2';
private $OnlyHere = 'only once';
function Test1($name){
$this->name=$name;
}
function output (){
foreach ($this as $k=>$that){
echo $k,'=',$that,'<br>';
}
if (isset($this->OnlyHere)) {echo $this->OnlyHere.'<br>';}
else {echo "just chickens!";}
echo '<b>I produce ', (($this->births) ?$this->births:'nothing'),'</b><br>' ;
echo '-----<br>';
}
function makeChild ($name="anonn"){
if($this->births) {
$this->hold[$name]=new $this->births($name);
return $this->hold[$name];
}
return false;
}
}
class Test2 extends Test1{
private $births = 'Test3';
}
class Test3 extends Test2{
private $births = false;// neuters class
}
$Test1=new Test1('Start');
$Test1->tesVar="And Ray";
$Test1->makeChild("first");
$Test1->hold['first']->makeChild('second');
echo'<pre>';
$Test1->hold['first']->output();
var_dump($Test1);
When property is PRIVATE it still appears in the var_dump of descendant objects, even if it was NOT declared in their classes ( I would expect this for PROTECTED, but not for PRIVATE). This is … the property isnt accessible… but it APPEARS to be set anyway?!?
Even weirder, if you re declare a private property so that it has a different value… then you have MULTIPLE intances of the same property ( again only the one recently declared is actually accessible form the class… but its still weird)
object(Test1)#1 (5) {
["tesVar"]=>
string(7) "And Ray"
["hold"]=>
array(1) {
["first"]=>
object(Test2)#2 (6) {
["births:private"]=>
string(5) "Test3"
["tesVar"]=>
string(8) "Veronica"
["hold"]=>
array(1) {
["second"]=>
[I] object(Test2)#3 (6) {
[B] ["births:private"]=>
string(5) "Test3"[/B]
["tesVar"]=>
string(8) "Veronica"
["hold"]=>
array(1) {
["anonn"]=>
object(Test2)#4 (6) {
["births:private"]=>
string(5) "Test3"
["tesVar"]=>
string(8) "Veronica"
["hold"]=>
array(0) {
}
["name:protected"]=>
string(5) "anonn"
["another"]=>
string(5) "other"
[B] ["births:private"]=>
string(5) "Test2"[/B]
}
}[/I]
["name:protected"]=>
string(6) "second"
["another"]=>
string(5) "other"
["births:private"]=>
string(5) "Test2"
}
}
["name:protected"]=>
string(5) "first"
["another"]=>
string(5) "other"
["births:private"]=>
string(5) "Test2"
}
}
["name:protected"]=>
string(5) "Start"
["another"]=>
string(5) "other"
["births:private"]=>
string(5) "Test2"
}
This ‘semi-duplication’ doesn’t occur if the property is set to PROTECTED instead of PRIVATE, still it doesn’t seem to be logical either way.
ALSO
In my test ‘only once’ should never be echoed since the property that contains it is PRIVATE and not inherited by child classes.
I would have expected, that in any object , BUT one of class TEST1, that isset( $this->OnlyHere) would be false.
Actually, it’s even more convoluted than that. What seems to be happening is the INHERITED FUNCTIONS ( output()), are executed in the root class and not at the instance class, and as such they also have access to all the PRIVATE root class properties. The solution would be to rewrite the EXACT SAME function within the first child class. But doesn’t that negate the point of OOP?
Could some one shed some ( simplified) light on this subject?