ホームページ >バックエンド開発 >PHPチュートリアル >这是php中__call和__callStatic在被继承后会产生的bug?
请看如下代码
<?php class A { public function __call($name, $args) { echo "NO\n"; } public static function __callStatic($name, $args) { echo "YES\n"; } } class B extends A { public function test() { A::test(); } public static function stest() { A::test(); } } A::test(); $b = new B(); $b->test(); B::stest();
以上代码将输出
YES NO YES
当我们在其他地方直接使用A::test
,它调用的是__callStatic
,输出是正常的YES
。
但是当我们用一个类B
继承A
以后,在B
的某个方法中使用A::test
,如果我们恰好又在A
中定义了__call
方法,这个是后A::test
就会去调用__call
。
这是否是php中的一个bug呢?
------------------ update -------------------
这里是@Laruence在blog(http://www.laruence.com/2012/06/14/26...)中提到的php作用域对类调用上下文的影响,但我在仔细阅读后发现我这里的问题有一定的特殊性
A
中定义了__callStatic
,所以A::test
调用的并不是不存在的static方法,但是它居然调用到__call
上去了.B
和A
的继承关系去掉,那么以上所有的输出都是YES
。A::test() == $this->test()
。这就是我的结论,而且按@Laruence的解释,php的设计在这里也是说的通的,但是这个设计是否合理,大家可以自己看着办吧。
------------------ update -------------------
已经在php的bug系统里面找到了跟我几乎一样的bug描述
https://bugs.php.net/bug.php?id=52713
最后回复显示已经在PHP 5.3.4里面修复了,但是我现在已经用的是5.3.13版本了,这个错误依然存在。
请看如下代码
<?php class A { public function __call($name, $args) { echo "NO\n"; } public static function __callStatic($name, $args) { echo "YES\n"; } } class B extends A { public function test() { A::test(); } public static function stest() { A::test(); } } A::test(); $b = new B(); $b->test(); B::stest();
以上代码将输出
YES NO YES
当我们在其他地方直接使用A::test
,它调用的是__callStatic
,输出是正常的YES
。
但是当我们用一个类B
继承A
以后,在B
的某个方法中使用A::test
,如果我们恰好又在A
中定义了__call
方法,这个是后A::test
就会去调用__call
。
这是否是php中的一个bug呢?
------------------ update -------------------
这里是@Laruence在blog(http://www.laruence.com/2012/06/14/26...)中提到的php作用域对类调用上下文的影响,但我在仔细阅读后发现我这里的问题有一定的特殊性
A
中定义了__callStatic
,所以A::test
调用的并不是不存在的static方法,但是它居然调用到__call
上去了.B
和A
的继承关系去掉,那么以上所有的输出都是YES
。A::test() == $this->test()
。这就是我的结论,而且按@Laruence的解释,php的设计在这里也是说的通的,但是这个设计是否合理,大家可以自己看着办吧。
------------------ update -------------------
已经在php的bug系统里面找到了跟我几乎一样的bug描述
https://bugs.php.net/bug.php?id=52713
最后回复显示已经在PHP 5.3.4里面修复了,但是我现在已经用的是5.3.13版本了,这个错误依然存在。
题设搞得有点迷惑,想想parent::test()? 静态与否在于calling scope,不在于:: 符号
对php不是特别熟,但如果php的类与C++的调用相同的话,这么是正常的。。。
你认为的第三条:
基于以上两点,我觉得在这里php认为A::test() == $this->test()。
这个是不正确的。。
你在B的非static函数中调用A::test(),php会认为是调用A类的非static函数,也就是$this->A::test(),而非A::test()
在B的static函数中调用A::test(),php会认为是调用A类的static函数,也就是A::test()
当然了,如果在cpp中不会这样,因为cpp不会像php同时存在
public static test();
public test();
这两个函数。。。。
静态与否在于calling scope,不在于:: 符号,这个学习了。
Class A {
public function __call($fun, $args) {
echo " __call\n";
}
public static function __callstatic($fun, $args) {
echo " __callstatic \n";
}
}
$ob= new A();
$ob->test();
A::test();