Hello, Do we keep the support added in http://bugs.php.net/bug.php?id=37632 (that isn't supported in C++, for instance) or fix the zend_is_callable_check_func() ?
Thanks. 2008/2/5, Robin Fernandes <[EMAIL PROTECTED]>: > 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 > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php