1

I am new to php and I was going through the documentation for the visibility. I am little confused with this example in the documentation. when the call to $myFoo->test() is made, shouldn't it make a call to Foos $this->testPrivate(); . I mean shouldn't $this be Foos Object rather than Bar object? . As per my knowledge(I might be wrong here) Foo will have kind of its own test() method which is inherited from Bar and calling $myFoo->test() will make a call to '$this->testPrivate' where the $this should be Foos object myFoo. so How is it calling Bar's testPrivate method?

class Bar 
{
public function test() {
    $this->testPrivate();
    $this->testPublic();
}

public function testPublic() {
    echo "Bar::testPublic\n";
}

private function testPrivate() {
    echo "Bar::testPrivate\n";
}
}

class Foo extends Bar 
{
public function testPublic() {
    echo "Foo::testPublic\n";
}

private function testPrivate() {
    echo "Foo::testPrivate\n";
}
}

$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
            // Foo::testPublic
?>
level0
  • 323
  • 1
  • 3
  • 13
  • The ambiguity of this constructed code should be taken as a warning sign. Avoid doing it in production code: Simply don't name two private methods the same when inheriting. If you assign the same name, the methods probably do the same, so you have code duplication. Or they look like they do the same, but don't - then they should have different names. – Sven Nov 29 '15 at 14:01

1 Answers1

5

test() is in Bar, and will call the highest-level methods that Bar has access to. It has access to Foo's testPublic (because it is public) so it can call that, but it doesn't have access to Foo's testPrivate() (because it's private to Foo) so it calls it's own testPrivate() instead

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
  • 1
    ...but even with `class Foo [...] public function testPrivate()` Bar::testPrivate() is invoked ;-) – VolkerK Nov 29 '15 at 12:17
  • yes , but how is `$this` changing its context. I am still confused ,shouldn't it be opposite ,in the sense Foo has access to **test()** because its public in **class Bar**. so Foo has its own test method inherited from Bar? – level0 Nov 29 '15 at 12:44
  • Even though php starts its lookup for the method on the instance/scope, the _context_ in this case is still `Bar`, not `Foo`. You can test that by removing Bar::testPrivate. The error message will be `Call to private method Foo::testPrivate() from context 'Bar'`. Why `Bar::testPrivate` is called even with public `Foo::testPrivate` I can only explain (right now; I'm currently an endangered species with this internet addiction thingy....) by linking to the handler code: https://github.com/php/php-src/blob/PHP-5.6.16/Zend/zend_object_handlers.c#L1071 – VolkerK Nov 29 '15 at 12:54