PHP method scope binding

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
6
down vote

favorite
1












I am confused by how PHP call method in parent-children hierarchy. Here is the code



class A 
private function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


The output is A!



consider another example, but only change the foo() method visibility in class A to be public.



class A 
public function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


This output is C!



Any explanation is welcome.










share|improve this question























  • Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
    – ArtisticPhoenix
    2 hours ago







  • 2




    @ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
    – Nero
    2 hours ago










  • @Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
    – deceze♦
    1 hour ago










  • I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
    – ArtisticPhoenix
    20 mins ago














up vote
6
down vote

favorite
1












I am confused by how PHP call method in parent-children hierarchy. Here is the code



class A 
private function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


The output is A!



consider another example, but only change the foo() method visibility in class A to be public.



class A 
public function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


This output is C!



Any explanation is welcome.










share|improve this question























  • Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
    – ArtisticPhoenix
    2 hours ago







  • 2




    @ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
    – Nero
    2 hours ago










  • @Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
    – deceze♦
    1 hour ago










  • I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
    – ArtisticPhoenix
    20 mins ago












up vote
6
down vote

favorite
1









up vote
6
down vote

favorite
1






1





I am confused by how PHP call method in parent-children hierarchy. Here is the code



class A 
private function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


The output is A!



consider another example, but only change the foo() method visibility in class A to be public.



class A 
public function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


This output is C!



Any explanation is welcome.










share|improve this question















I am confused by how PHP call method in parent-children hierarchy. Here is the code



class A 
private function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


The output is A!



consider another example, but only change the foo() method visibility in class A to be public.



class A 
public function foo()
echo "A!";

public function test()
$this->foo();



class C extends A
public function foo()
echo 'C!';



$c = new C();
$c->test();


This output is C!



Any explanation is welcome.







php oop object






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago

























asked 2 hours ago









Nero

587312




587312











  • Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
    – ArtisticPhoenix
    2 hours ago







  • 2




    @ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
    – Nero
    2 hours ago










  • @Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
    – deceze♦
    1 hour ago










  • I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
    – ArtisticPhoenix
    20 mins ago
















  • Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
    – ArtisticPhoenix
    2 hours ago







  • 2




    @ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
    – Nero
    2 hours ago










  • @Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
    – deceze♦
    1 hour ago










  • I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
    – ArtisticPhoenix
    20 mins ago















Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
– ArtisticPhoenix
2 hours ago





Private methods are only visible to the actual class, protected is visible only inside the class (any child class). Public is for the world to see. In your fist example calling foo will fail in any case except from within the class it's defined within. When you override foo in the child, it doesn't replace the private foo method because it's not visible to the C class at all.
– ArtisticPhoenix
2 hours ago





2




2




@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
– Nero
2 hours ago




@ArtisticPhoenix thanks for comment, but I don't think that solve my confusion. Maybe you can explain in more details using above example.
– Nero
2 hours ago












@Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
– deceze♦
1 hour ago




@Artistic foo is only called from within the class that defines it. The question is why test sticks to calling A::foo instead of C::foo.
– deceze♦
1 hour ago












I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
– ArtisticPhoenix
20 mins ago




I tried, it's like relativity it's all depends on the reference frame of the observer. You can't think of it in terms of the Global space (space outside the classes).
– ArtisticPhoenix
20 mins ago












6 Answers
6






active

oldest

votes

















up vote
3
down vote



accepted










Rule: private and final methods on an object will always be called directly, without consulting the override table.



This rule is baked into the engine:



/* Check if this calls a known method on $this */
if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
CG(active_class_entry) && zend_is_scope_known()) ZEND_ACC_FINAL)))
fbc = NULL;




"Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.



I admit the docs could better spell this out, however.






share|improve this answer





























    up vote
    1
    down vote













    This is the behavior in most languages (by design).



    If a method is private, $this->method() will call it directly (ignore the derived class's method)



    If a method is virtual (this concept comes from C++, in PHP and Java, all public/protected methods are virtual), $this->method() will call the derived class's method.



    Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze






    share|improve this answer






















    • Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
      – deceze♦
      1 hour ago










    • Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
      – Nero
      1 hour ago










    • @deceze yes, it is the OOP concern. I agree with your explanation
      – shawn
      1 hour ago










    • My English is not very good, maybe you can help to edit the answer :) @deceze
      – shawn
      1 hour ago


















    up vote
    1
    down vote













    I think the answer lies on the official documentation. doc here



    In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope



    As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).






    share|improve this answer






















    • Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
      – bishop
      1 min ago

















    up vote
    0
    down vote













    Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
    When extending A class, C inherits all public and protected classes of it, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.






    share|improve this answer




















    • A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
      – Nero
      1 hour ago

















    up vote
    0
    down vote













    Because in first case you are not overriding the foo() in derived class C, because foo() is private.



    But, in case two, foo() is public and is overridden by function foo() in class C



    So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.



    Try this:



    public function test() 
    echo get_class($this);
    $this->foo();



    In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.






    share|improve this answer










    New contributor




    Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.

















    • Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
      – bishop
      6 mins ago


















    up vote
    0
    down vote













    Ok let me try [Again]



    Basically both methods exist side by side.



    Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.



    The reason they can exist side by side, is inside of the child class when you call $this->foo() there is no ambiguity about which foo is being called as only the public version is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.



    Now from the parents call to its own private method. This is where most people get confused. You asked




    When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo




    It doesn't because you are calling the private method from another method in the same class where the private one was defined. If it didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.






    share|improve this answer






















    • When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
      – deceze♦
      1 hour ago











    • It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
      – ArtisticPhoenix
      1 hour ago







    • 1




      Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
      – Nero
      1 hour ago







    • 1




      Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
      – Nero
      55 mins ago











    • Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
      – ArtisticPhoenix
      38 mins ago











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53111792%2fphp-method-scope-binding%23new-answer', 'question_page');

    );

    Post as a guest






























    6 Answers
    6






    active

    oldest

    votes








    6 Answers
    6






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    Rule: private and final methods on an object will always be called directly, without consulting the override table.



    This rule is baked into the engine:



    /* Check if this calls a known method on $this */
    if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
    CG(active_class_entry) && zend_is_scope_known()) ZEND_ACC_FINAL)))
    fbc = NULL;




    "Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.



    I admit the docs could better spell this out, however.






    share|improve this answer


























      up vote
      3
      down vote



      accepted










      Rule: private and final methods on an object will always be called directly, without consulting the override table.



      This rule is baked into the engine:



      /* Check if this calls a known method on $this */
      if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
      CG(active_class_entry) && zend_is_scope_known()) ZEND_ACC_FINAL)))
      fbc = NULL;




      "Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.



      I admit the docs could better spell this out, however.






      share|improve this answer
























        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        Rule: private and final methods on an object will always be called directly, without consulting the override table.



        This rule is baked into the engine:



        /* Check if this calls a known method on $this */
        if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
        CG(active_class_entry) && zend_is_scope_known()) ZEND_ACC_FINAL)))
        fbc = NULL;




        "Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.



        I admit the docs could better spell this out, however.






        share|improve this answer














        Rule: private and final methods on an object will always be called directly, without consulting the override table.



        This rule is baked into the engine:



        /* Check if this calls a known method on $this */
        if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
        CG(active_class_entry) && zend_is_scope_known()) ZEND_ACC_FINAL)))
        fbc = NULL;




        "Why", you ask? The answer is: because that's how it works. In language design, this is called "name hiding", and it's up to the language to specify how name hiding works. Take C++ for example. It has well-defined, and complex name hiding rules. PHP has its own rules. They're different from C++. But they're unique to PHP. This is just something you have to memorize about the language.



        I admit the docs could better spell this out, however.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 10 mins ago

























        answered 19 mins ago









        bishop

        22.7k46086




        22.7k46086






















            up vote
            1
            down vote













            This is the behavior in most languages (by design).



            If a method is private, $this->method() will call it directly (ignore the derived class's method)



            If a method is virtual (this concept comes from C++, in PHP and Java, all public/protected methods are virtual), $this->method() will call the derived class's method.



            Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze






            share|improve this answer






















            • Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
              – deceze♦
              1 hour ago










            • Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
              – Nero
              1 hour ago










            • @deceze yes, it is the OOP concern. I agree with your explanation
              – shawn
              1 hour ago










            • My English is not very good, maybe you can help to edit the answer :) @deceze
              – shawn
              1 hour ago















            up vote
            1
            down vote













            This is the behavior in most languages (by design).



            If a method is private, $this->method() will call it directly (ignore the derived class's method)



            If a method is virtual (this concept comes from C++, in PHP and Java, all public/protected methods are virtual), $this->method() will call the derived class's method.



            Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze






            share|improve this answer






















            • Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
              – deceze♦
              1 hour ago










            • Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
              – Nero
              1 hour ago










            • @deceze yes, it is the OOP concern. I agree with your explanation
              – shawn
              1 hour ago










            • My English is not very good, maybe you can help to edit the answer :) @deceze
              – shawn
              1 hour ago













            up vote
            1
            down vote










            up vote
            1
            down vote









            This is the behavior in most languages (by design).



            If a method is private, $this->method() will call it directly (ignore the derived class's method)



            If a method is virtual (this concept comes from C++, in PHP and Java, all public/protected methods are virtual), $this->method() will call the derived class's method.



            Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze






            share|improve this answer














            This is the behavior in most languages (by design).



            If a method is private, $this->method() will call it directly (ignore the derived class's method)



            If a method is virtual (this concept comes from C++, in PHP and Java, all public/protected methods are virtual), $this->method() will call the derived class's method.



            Rule is rule, it is an OOP concern. For example, in OOP we may want to make sure a method never got overridden, then we can make it private. If a developer overrides it by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation. Thanks to @deceze







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            shawn

            2,465616




            2,465616











            • Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
              – deceze♦
              1 hour ago










            • Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
              – Nero
              1 hour ago










            • @deceze yes, it is the OOP concern. I agree with your explanation
              – shawn
              1 hour ago










            • My English is not very good, maybe you can help to edit the answer :) @deceze
              – shawn
              1 hour ago

















            • Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
              – deceze♦
              1 hour ago










            • Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
              – Nero
              1 hour ago










            • @deceze yes, it is the OOP concern. I agree with your explanation
              – shawn
              1 hour ago










            • My English is not very good, maybe you can help to edit the answer :) @deceze
              – shawn
              1 hour ago
















            Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
            – deceze♦
            1 hour ago




            Is there an "official" reasoning for this? What I'd cobble together as an explanation would be something like: child classes should not be aware of the existence of private methods, if they override them it would be by accident, and would hence introduce weird behaviour if the parent suddenly called the child's implementation…?
            – deceze♦
            1 hour ago












            Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
            – Nero
            1 hour ago




            Thanks. you just remind me something and it's explained in the office doc. It has the same explanation as yours. the private method has higher precedence.
            – Nero
            1 hour ago












            @deceze yes, it is the OOP concern. I agree with your explanation
            – shawn
            1 hour ago




            @deceze yes, it is the OOP concern. I agree with your explanation
            – shawn
            1 hour ago












            My English is not very good, maybe you can help to edit the answer :) @deceze
            – shawn
            1 hour ago





            My English is not very good, maybe you can help to edit the answer :) @deceze
            – shawn
            1 hour ago











            up vote
            1
            down vote













            I think the answer lies on the official documentation. doc here



            In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope



            As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).






            share|improve this answer






















            • Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
              – bishop
              1 min ago














            up vote
            1
            down vote













            I think the answer lies on the official documentation. doc here



            In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope



            As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).






            share|improve this answer






















            • Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
              – bishop
              1 min ago












            up vote
            1
            down vote










            up vote
            1
            down vote









            I think the answer lies on the official documentation. doc here



            In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope



            As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).






            share|improve this answer














            I think the answer lies on the official documentation. doc here



            In non-static contexts, the called class will be the class of the object instance. Since $this-> will try to call private methods from the same scope



            As a note, though this could eliminate my confusion, simply saying "that is the way it is" seem not enough. Because it's weird behavior. It's not as clear as the late static binding nor respect to the called scope class C (which can be verified using get_called_class() in test() method ).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 1 hour ago

























            answered 1 hour ago









            Nero

            587312




            587312











            • Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
              – bishop
              1 min ago
















            • Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
              – bishop
              1 min ago















            Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
            – bishop
            1 min ago




            Yes, this is the documented reason, but I feel it could be clarified. As unsatisfying as it may sound, that's just the way it is. :)
            – bishop
            1 min ago










            up vote
            0
            down vote













            Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
            When extending A class, C inherits all public and protected classes of it, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.






            share|improve this answer




















            • A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
              – Nero
              1 hour ago














            up vote
            0
            down vote













            Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
            When extending A class, C inherits all public and protected classes of it, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.






            share|improve this answer




















            • A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
              – Nero
              1 hour ago












            up vote
            0
            down vote










            up vote
            0
            down vote









            Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
            When extending A class, C inherits all public and protected classes of it, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.






            share|improve this answer












            Private foo() is a part of class A, and A does not know about the existence of the C class. It can work without it.
            When extending A class, C inherits all public and protected classes of it, that's why test() is available. You would call the private foo() method of A class from within the test() method, not the one from C. Extending works in one direction only, you would not be able to call methods from C from within A. A can be instantiated without C and nothing can guarantee another class will extend it.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 1 hour ago









            Marius S

            146113




            146113











            • A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
              – Nero
              1 hour ago
















            • A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
              – Nero
              1 hour ago















            A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
            – Nero
            1 hour ago




            A does not know about the existence of the C class, but why after change visibility of foo method in class A make it know about the existence of the C class?
            – Nero
            1 hour ago










            up vote
            0
            down vote













            Because in first case you are not overriding the foo() in derived class C, because foo() is private.



            But, in case two, foo() is public and is overridden by function foo() in class C



            So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.



            Try this:



            public function test() 
            echo get_class($this);
            $this->foo();



            In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
              – bishop
              6 mins ago















            up vote
            0
            down vote













            Because in first case you are not overriding the foo() in derived class C, because foo() is private.



            But, in case two, foo() is public and is overridden by function foo() in class C



            So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.



            Try this:



            public function test() 
            echo get_class($this);
            $this->foo();



            In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

















            • Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
              – bishop
              6 mins ago













            up vote
            0
            down vote










            up vote
            0
            down vote









            Because in first case you are not overriding the foo() in derived class C, because foo() is private.



            But, in case two, foo() is public and is overridden by function foo() in class C



            So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.



            Try this:



            public function test() 
            echo get_class($this);
            $this->foo();



            In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.






            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            Because in first case you are not overriding the foo() in derived class C, because foo() is private.



            But, in case two, foo() is public and is overridden by function foo() in class C



            So, by basics of inheritance you can't override a private method and hence your foo() in class C has no existence in first case (keeping or deleting it does not matter) and the actual method of extended class A will be called since you have no right to override it in your class.



            Try this:



            public function test() 
            echo get_class($this);
            $this->foo();



            In both case it will echo C , not A. So, $this is object of C which cannot override private methods of A, hence foo() of C has no use when foo() exists in class A and is private.







            share|improve this answer










            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            share|improve this answer



            share|improve this answer








            edited 21 mins ago





















            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.









            answered 1 hour ago









            Manpreet

            163




            163




            New contributor




            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





            New contributor





            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.






            Manpreet is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.











            • Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
              – bishop
              6 mins ago

















            • Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
              – bishop
              6 mins ago
















            Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
            – bishop
            6 mins ago





            Your last paragraph underscores the reason for the confusion, I think, and your earlier paragraphs don't help clarify that confusion, in my opinion. If in both cases the object $this is of class C, then there's a reasonable expectation that C::foo() will be called regardless of the existence of A::foo(). However, the OP demonstrates that's not the case and wants to know why. The answer, as it turns out, cannot be explained by rationalization based on inheritance -- it's simply a rule the engine implements, and it must be memorized.
            – bishop
            6 mins ago











            up vote
            0
            down vote













            Ok let me try [Again]



            Basically both methods exist side by side.



            Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.



            The reason they can exist side by side, is inside of the child class when you call $this->foo() there is no ambiguity about which foo is being called as only the public version is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.



            Now from the parents call to its own private method. This is where most people get confused. You asked




            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo




            It doesn't because you are calling the private method from another method in the same class where the private one was defined. If it didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.






            share|improve this answer






















            • When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
              – deceze♦
              1 hour ago











            • It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
              – ArtisticPhoenix
              1 hour ago







            • 1




              Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
              – Nero
              1 hour ago







            • 1




              Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
              – Nero
              55 mins ago











            • Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
              – ArtisticPhoenix
              38 mins ago















            up vote
            0
            down vote













            Ok let me try [Again]



            Basically both methods exist side by side.



            Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.



            The reason they can exist side by side, is inside of the child class when you call $this->foo() there is no ambiguity about which foo is being called as only the public version is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.



            Now from the parents call to its own private method. This is where most people get confused. You asked




            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo




            It doesn't because you are calling the private method from another method in the same class where the private one was defined. If it didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.






            share|improve this answer






















            • When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
              – deceze♦
              1 hour ago











            • It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
              – ArtisticPhoenix
              1 hour ago







            • 1




              Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
              – Nero
              1 hour ago







            • 1




              Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
              – Nero
              55 mins ago











            • Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
              – ArtisticPhoenix
              38 mins ago













            up vote
            0
            down vote










            up vote
            0
            down vote









            Ok let me try [Again]



            Basically both methods exist side by side.



            Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.



            The reason they can exist side by side, is inside of the child class when you call $this->foo() there is no ambiguity about which foo is being called as only the public version is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.



            Now from the parents call to its own private method. This is where most people get confused. You asked




            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo




            It doesn't because you are calling the private method from another method in the same class where the private one was defined. If it didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.






            share|improve this answer














            Ok let me try [Again]



            Basically both methods exist side by side.



            Private by design means that this thing (method or property) is not viable or overwriteable by a descendant object.



            The reason they can exist side by side, is inside of the child class when you call $this->foo() there is no ambiguity about which foo is being called as only the public version is visible to this class, in this case. You could make it private in the child and only that one would be visible to it. Also you could have a class between the parent and child with it's public method and no method in the last child and he would see the last public method defined. In shot there is only one Foo available to the child class, so there is no way it can be confused with the private version.



            Now from the parents call to its own private method. This is where most people get confused. You asked




            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo




            It doesn't because you are calling the private method from another method in the same class where the private one was defined. If it didn't call the private method but instead called the child method from the method in the parent, that would completely defeat the reason for private. And, it would lose any value it has. In essence it would be meaningless and we wouldn't be discussing the finer points of it.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 13 mins ago

























            answered 1 hour ago









            ArtisticPhoenix

            14.4k11223




            14.4k11223











            • When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
              – deceze♦
              1 hour ago











            • It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
              – ArtisticPhoenix
              1 hour ago







            • 1




              Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
              – Nero
              1 hour ago







            • 1




              Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
              – Nero
              55 mins ago











            • Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
              – ArtisticPhoenix
              38 mins ago

















            • When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
              – deceze♦
              1 hour ago











            • It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
              – ArtisticPhoenix
              1 hour ago







            • 1




              Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
              – Nero
              1 hour ago







            • 1




              Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
              – Nero
              55 mins ago











            • Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
              – ArtisticPhoenix
              38 mins ago
















            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
            – deceze♦
            1 hour ago





            When calling what is for all intents and purposes C::test, why does it prefer the private A::foo over the public C::foo?
            – deceze♦
            1 hour ago













            It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
            – ArtisticPhoenix
            1 hour ago





            It doesn't prefer it. Your thinking in terms of it over writing or replacing that method, which it doesn't do. It simply doesn't exist.
            – ArtisticPhoenix
            1 hour ago





            1




            1




            Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
            – Nero
            1 hour ago





            Explanation like class A does not know about existence of class B seem make no sense to me especially when we're talking with my example. the way you try to prove this is wrong, because you use (new A)->test(); but in my case, it's (new C)->test(); They are different. You call parent directly and of course it won't know. In my case, it makes call from a child. Correct me if wrong.
            – Nero
            1 hour ago





            1




            1




            Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
            – Nero
            55 mins ago





            Additionally, if you remove function foo() from class A, the one defined in child will be called. Dose this prove "class A is aware of class C's existence" ?
            – Nero
            55 mins ago













            Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
            – ArtisticPhoenix
            38 mins ago





            Dose this prove "class A is aware of class C's existence" No because your calling it from an instance of the child. And even though you call the private method from an child instance private overrides that normal behaviour. If it didn't there would be no point in having it.
            – ArtisticPhoenix
            38 mins ago


















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53111792%2fphp-method-scope-binding%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

            Confectionery