PHP Private Class Member Visibility
PHP's handling of "private" fields/members of a class may surprise you. Normally, a private field is only accessible by the methods of the class itself. In fact, even classes that extend another may not access the parent class's private members.
However, if you were to pass a separate, external instance of a class to another one of the same type, you may be surprised to find out that the class can actually access the private members of the injected class.
Code speaks clearer than words:
Code
<?php
class Doge
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
public function equalsWithSameType(self $other)
{
return ($other->name === $this->name);
}
public function equalsWithSubType(DogeCoin $sub)
{
return ($sub->name === $this->name);
}
public function equalsWithRandomType(SomethingElseCompletely $whatever_man)
{
return ($whatever_man->name === $this->name);
}
}
class DogeCoin extends Doge
{
private $name;
}
class SomethingElseCompletely
{
private $name;
public function __construct($name) {
$this->name = $name;
}
}
$first_doge = new Doge('a');
$second_doge = new Doge('a');
$doge_coin = new DogeCoin('a');
$something_else_completely = new SomethingElseCompletely('a');
var_dump($first_doge->equalsWithSameType($second_doge));
var_dump($first_doge->equalsWithSubType($doge_coin));
var_dump($first_doge->equalsWithRandomType($something_else_completely));
Output
bool(true)
bool(true)
Fatal error: Cannot access private property SomethingElseCompletely::$name in /in/dsdtr on line 30
Process exited with code 255.
Oh, and here it is on multiple versions if you're curious: http://3v4l.org/dsdtr
Seems strange, huh? Although its documented, it still seems like strange behavior.
(Source http://www.php.net/manual/en/language.oop5.visibility.php#language.oop5.visibility-other-objects)
Written by Trevor N. Suarez
Related protips
3 Responses
Well, it's not surprising at all. It makes a lot of sense.
Correct me if I'm wrong, but Java and ActionScript also share the same concept. If this was restricted (as in c#), there would be no point in static private members.
Your tip maks no sense at all. It's the expected behaviour, since you're injecting an instance of a class (== object) with all it's attributes and methods.
I don't get, why the other comments say, it makes sense. Calling $totallyDifferentObject->myPrivateProperty
shouldn't work (--> encapsulation) and especially it shouldn't depend on where it happens :?