2

It may sound silly, but I'm new in PHP. I was learning from the documentation about access specifiers when I came to this section.

class Bar {
    public function __construct() {
        echo "Bar::constructor<br />";
    }
    public function test() {
        $this->PublicTest();
        $this->PrivateTest();
        $this->protectedTest();
    }
    public function PublicTest(){
        echo "Bar::testPublic<br />";
    }
    private function PrivateTest() {
        echo "Bar::testPrivate<br />";
    }
    protected function ProtectedTest() {
        echo "Bar::testProtected<br />";
    }
}

class Foo extends Bar {
    public function __construct() {
        echo "Foo::constructor<br />";
    }
    public function PublicTest() {
        echo "Foo::testPublic<br />";
    }
    private function PrivateTest() {
        echo "Foo::testPrivate<br />";
    }
    protected function ProtectedTest() {
        echo "Foo::testProtected<br />";
    }
}

$myFoo = new Foo();
$myFoo->test();

?>

This produces output as:

Foo::constructor
Foo::testPublic
Bar::testPrivate
Foo::testProtected

Why does it prints from Bar class for private function while it prints from Foo class for public and protected function? Since, i don't have test() function in Foo class, it accesses the test() function from Bar class.

Where does $this pointer point to? Does it point to the function of Foo class or functions of Bar class? I'm really confused here. Can someone please explain this to me? Any help would be so much appreciated.

dhh
  • 4,289
  • 8
  • 42
  • 59
Bivek
  • 1,380
  • 10
  • 24
  • here is a similar thread that might help http://stackoverflow.com/questions/4361553/php-public-private-protected – brad Aug 09 '16 at 18:43
  • @brad Thanks... But that didn't clarify my doubt though. :( – Bivek Aug 09 '16 at 18:59
  • private equals only that class can see it public = anyone can see and access it protected means it and any class that extends it can see. I am not 100% sure but I believe Foo class is using its local copy of PublicTest and ProtectedTest..... – brad Aug 09 '16 at 19:06
  • 1
    @brad I'm confused about $this pointer. When the control goes to test() function, where does $this pointer actually points and why? – Bivek Aug 09 '16 at 19:18
  • $this is the current object....maybe self::PublicTest(); would yield what you are thinking it should when you make new Foo(); $this-> is referring to the current object you are making not the current class – brad Aug 09 '16 at 19:47
  • 1
    It doesn't make much sense but, well, this is how the methods visibility is implemented in PHP. Using the terminology of C++, the protected and public methods in PHP are `virtual` (the version that is called matches the class of `$this`), the private ones are not (they match the class of the function that calls them). – axiac Aug 18 '16 at 21:38

2 Answers2

0

$this is the current object....maybe self::PublicTest(); would yield what you are thinking it should when you make new Foo(); $this-> is referring to the current object you made, not the current class –

class Animal {

     public function whichClass() {
        echo "I am an Animal!";
    }

   /* This method has been changed to use the 
       self keyword instead of $this
   */

    public function sayClassName() {
       self::whichClass();
    }

}

class Tiger extends Animal {

    public function whichClass() {
        echo "I am a Tiger!";
    }

}

$tigerObj = new Tiger();
$tigerObj->sayClassName();

this will produce I am an Animal!

this was taken from http://www.programmerinterview.com

brad
  • 993
  • 7
  • 10
0

That's because of the visibility of each class/function. When we call test() at first, using this:

$myFoo = new Foo();
$myFoo->test();

We call the test() inside Bar class, since Foo extends Bar and it uses test() of Bar because it's public and is visible in class Foo. Now, inside foo() of Bar class, these 3 functions are called:

$this->PublicTest();
$this->PrivateTest();
$this->protectedTest();

Here, we are inside Bar class right now and hence it can see PrivateTest() and ProtectedTest() of it's own class only. Because the visibility of these functions are set to Private and Protected. But in case of PublicTest(), it can see 2 functions. Because PublicTest() is set to Public visibility for both Foo and Bar class. Here, Public function of Bar class is chosen although Foo class has its own PublicTest() because of following reason:

Since, we are using $this handler, which always reference to the object currently being used (which is of Foo class in this case), it chooses PublicTest() of Foo class.

Bivek
  • 1,380
  • 10
  • 24