Heim >Backend-Entwicklung >PHP-Tutorial >这是php中__call和__callStatic在被继承后会产生的bug?

这是php中__call和__callStatic在被继承后会产生的bug?

WBOY
WBOYOriginal
2016-06-06 20:52:061022Durchsuche

请看如下代码

<?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作用域对类调用上下文的影响,但我在仔细阅读后发现我这里的问题有一定的特殊性

  1. 我在A中定义了__callStatic,所以A::test调用的并不是不存在的static方法,但是它居然调用到__call上去了.
  2. 如果我把BA的继承关系去掉,那么以上所有的输出都是YES
  3. 基于以上两点,我觉得在这里php认为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作用域对类调用上下文的影响,但我在仔细阅读后发现我这里的问题有一定的特殊性

  1. 我在A中定义了__callStatic,所以A::test调用的并不是不存在的static方法,但是它居然调用到__call上去了.
  2. 如果我把BA的继承关系去掉,那么以上所有的输出都是YES
  3. 基于以上两点,我觉得在这里php认为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();

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn