1

Why can you call a private method on a new instance made inside a public method of the same class type?

class Foo
{
    private function thePrivateMethod()
    {
        echo 'can not be called publicly?';
    }

    public function thePublicMethod()
    {
        $clone = new Foo;
        $clone->thePrivateMethod();
    }
}

$foo = new Foo();
$foo->thePublicMethod();
$foo->thePrivateMethod();

The above results in the following output when run in PHP 7.3.18

can not be called publicly?

Fatal error:  Uncaught Error: Call to private method Foo::thePrivateMethod() from context

Intuitively, I would expect the first call to Foo::thePrivateMethod() to also cause a fatal error. But I'm not able to find in the documentation that this behaviour would be allowed?

gawpertron
  • 1,867
  • 3
  • 21
  • 37
  • 6
    https://www.php.net/manual/en/language.oop5.visibility.php#language.oop5.visibility-other-objects: _"Objects of the same type will have access to each others private and protected members even though they are not the same instances. This is because the implementation specific details are already known when inside those objects."_ – CBroe Dec 22 '21 at 10:53
  • well there you go, thats the answer, it's built into php to be like that on purpose. – gawpertron Dec 22 '21 at 10:59
  • @gawpertron: Perhaps you can add a bit more context about your expectation of the fatal error (that is not there)? – hakre Dec 22 '21 at 11:01

1 Answers1

0

Basically, following the Object Oriented paradigm you can always call a private or protected method within the own class. Here is a table that can explain better the concept behind 'Why does this work?'

Table OOP

The first time, you call a public method that recall a private method within the context of the class, so it's allowed. The second time, you call directly a private method, that is not allowed outside the class.

Is the same concept of the attributes, if you declare aprivate $test within the class, you cannot access to it by $foo = new Foo();$foo -> test;

but instead, you need to declare a public method that do this for you, and then call it to get the value of $test : $foo -> getTest();

NB. since you have init the object within the context of the class, it's always allowed.

Biagio Boi
  • 58
  • 6