Last Updated: February 25, 2016
·
6.618K
· rican7

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.

Picture

(Source http://www.php.net/manual/en/language.oop5.visibility.php#language.oop5.visibility-other-objects)

3 Responses
Add your response

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.

over 1 year ago ·

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.

over 1 year ago ·

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 :?

over 1 year ago ·