1

我得到了一些奇怪的结果,最好通过显示代码来解释。

假设我创建了一个具有 3 个方法的 A 类:
添加方法 - 添加其他要在以后使用的 A 类实例
_调用魔术方法 - 添加动态变量和值
_callStatic静态魔法方法 - 这个方法帮助我创建更具可读性的 A 类

所以课程是:

class A_Class {

protected $name;
protected $varList;
protected $childs = array();

protected static $tabCount = 0;

public function __construct($name) {
    $this->name = $name;
}

public function add() {
    if (func_num_args()) { 
        $this->childs = array_merge($this->childs, func_get_args());
    }
    return $this;
}

public function __call($name, $arguments) {
    if (count($arguments) > 0) {
        $this->varList[$name] = $arguments[0];
    }
    return $this;
}

public static function __callStatic($name, $arguments) {
    return new A_Class($name);
}

}

现在当我使用它时:

$a = A_Class::MyNameA();
$a->someDynamicVar("I am the var data");
$a->add(A_Class::ANotherNameA());
print_r($a);

工作得很好,导致:

A_Class Object
(
    [name:protected] => MyNameA
    [varList:protected] => Array
        (
            [someDynamicVar] => I am the var data
        )

    [childs:protected] => Array
        (
        )
)

但是,如果我尝试创建类 B 作为从类 A 的继承,如下所示:

class B_Class extends A_Class {

public function __construct($name) {
    parent::__construct($name);
    $this->add(A_Class::NewAClass());
}

}

并尝试以下操作:

$b = new B_Class("NewBClassInstance");
print_r($b);

我得到一个递归结果:

B_Class Object
(
    [name:protected] => B-MAN
    [varList:protected] => 
    [childs:protected] => Array
        (
            [0] => B_Class Object
 *RECURSION*
        )
)

对我来说这很奇怪。
好像 __callStatic 是从 B 类而不是 A 类运行的

有任何想法吗 ?

4

1 回答 1

1

也许这个例子会帮助你理解:

<?php

class A
{
  public function __call($name, $args)
  {
    echo "__call\n";
  }

  static public function __callStatic($name, $args)
  {
    echo "__callStatic\n";
  }
}

class B extends A
{
  public function __construct()
  {
    A::callMe();
  }
}

new B();

运行结果如下:

__call

它不调用静态版本。为什么?因为 B 是 A 的后裔,因此当两者都存在A::foo()时是一个模棱两可的调用。__call__callStatic

请记住,在类的成员函数的上下文中,这并不Class::func() 意味着“调用类中命名的静态方法”。funcClass

它只是意味着“调用Class的函数名为func”。例如:

class A
{
  public function foo() {}
}

class B
{
  public function foo() {}

  public function bar()
  {
    A::foo(); // call A's foo
  }
}

因此,在您的情况下,该__call方法在 B 的构造函数中被调用。这正是 PHP 在这种模棱两可的情况下所做的。它返回$this传递给 的内容$this->add(),有效地为您提供:$this->add($this)在 B 的构造函数中。

同样,这些都不意味着在类成员函数的上下文中“调用静态函数”:

parent::foo();
self::foo();
static::foo();
A::foo();
B::foo();

它们都只是表示“在类中调用函数 foo,由 :: 左侧的东西引用”。通常你要么有一个显式的实例函数,要么有一个静态函数,所以调用是没有歧义的。但是当你同时拥有__call和时__callStatic,PHP 无法知道你想调用哪个,它总是选择__call.

于 2012-08-05T18:24:30.987 回答