Hi all, in my point view, the zend_check_protected should be used like: http://ecl.mediain.com.br/diff/protected.diff
This patch breaks a test (Zend/tests/bug37632.phpt): class A1 { protected function test() { echo __METHOD__ . "\n"; } } class B1 extends A1 { public function doTest(A1 $obj) { echo __METHOD__ . "\n"; $obj->test(); } } class C1 extends A1 { protected function test() { echo __METHOD__ . "\n"; } } $b = new B1; $b->doTest(new C1); [...] However, this also looks wrong to me. Em Ter, 2008-02-05 às 11:43 +0000, Robin Fernandes escreveu: > Hi all, > > The fix to bug 37212 (http://bugs.php.net/bug.php?id=37632) introduced > an unusual method accessibility rule. A class can access a protected > method declared outside of its own direct class hierarchy if that > method has a prototype in a common superclass. > > <?php > class A { > static protected function f() {return 'A::f()';} > } > class B1 extends A { > static protected function f() {return 'B1::f()';} > } > class B2 extends A { > static public function test() {echo B1::f();} > } > B2::test(); // prints B1::f() > ?> > > This is achieved using by zend_get_function_root_class() when invoking > zend_check_protected(), e.g.: > zend_check_protected(zend_get_function_root_class(fbc), EG(scope)) > > Looking at other uses of zend_check_protected() reveals at least 5 > cases where this rule is not enforced. They are illustrated below. So > is the rule itself incorrect? or should the inconsistent cases be > fixed? > > > The examples below were tested on 5.2.5 and the latest 5.3 and 6.0 snaps. > > 1. The visibility rule does not apply to properties (static or not): > <?php > class A { > protected $p = 'A::$p'; > static protected $sp = 'A::$sp'; > } > class B1 extends A { > protected $p = 'B1::$p'; > static protected $sp = 'B1::$sp'; > } > class B2 extends A { > static public function test() { > $b1 = new B1; > echo $b1->p; //Fatal error: Cannot access protected property > B1::$p > echo B1::$sp; //Fatal error: Cannot access protected property > B1::$sp > } > } > B2::test(); > ?> > > > 2. It doesn't apply to callbacks either: > <?php > class A { > static protected function f() {return 'A::f()';} > } > class B1 extends A { > static protected function f() {return 'B1::f()';} > } > class B2 extends A { > static public function test() { > echo call_user_func('B1::f'); > } > } > B2::test(); // Warning: call_user_func() expects parameter 1 to be a > valid callback, cannot access protected method B1::f() > ?> > > > 3. is_callable() doesn't know about this visibility rule: > <?php > class A { > static protected function f() {return 'A::f()';} > } > class B1 extends A { > static protected function f() {return 'B1::f()';} > } > class B2 extends A { > static public function test() { > var_dump(is_callable('B1::f')); // returns false > B1::f(); // works > } > } > B2::test(); > ?> > > > 4. The rule does not apply to the clone magic method: > <?php > class A { > protected function f() {return 'A::f()';} > protected function __clone() {} > } > class B1 extends A { > protected function f() {return 'B1::f()';} > protected function __clone() {} > } > class B2 extends A { > static public function test($obj) { > echo $obj->f(); // works > clone $obj; // Fatal error: Call to protected B1::__clone() > from context 'B2' > } > } > B2::test(new B1); > ?> > > > 5. The rule does not apply to destructors: > <?php > class A { > protected function __destruct() {} > } > class B1 extends A { > protected function __destruct() {} > } > class B2 extends A { > static public function test() { > $obj = new B1; > } // Fatal error: Call to protected B1::__destruct() from context 'B2' > } > B2::test(); > ?> > > Many thanks, > Robin > -- Regards, Felipe Pena. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php