PHP method scope binding

  • A+
Category:Languages

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.

 


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_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);     fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);      /* We only know the exact method that is being called if it is either private or final.      * Otherwise an overriding method in a child class may be called. */     if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE|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.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: