【问题标题】:Weird behaviour with triggering __callStatic() from non-static method从非静态方法触发 __callStatic() 的奇怪行为
【发布时间】:2012-02-27 17:24:44
【问题描述】:

我在 PHP 类 (v5.3.8) 中发现了这种奇怪的行为。

你有:

class foo {
  function __call($func, $args) {
    if ($func == 'bar')
      echo "non-static __call";
  }

  static function __callStatic($func, $args) {
    if ($func == 'bar')
      echo "__callStatic";
  }

  function callMe() {
    self::bar();
  }
}

然后你做:

foo::bar() // outputs '__callStatic' as expected.
$f = new foo;
$f->callMe(); // outputs 'non-static __call', as I did not expect.

您会看到,从非静态函数调用的不存在的静态方法会触发 __call() 而不是 __callStatic()。我想知道这是否应该像这样工作还是这是某种错误?

[编辑]

我忘了在callMe() 上尝试static::bar(); 但不,它也没有用。

我(想我)理解 inhan 的评论,但仍然......如果我调用的是类本身,而不是实例或对象,我的直接逻辑说它应该触发 __callStatic()。哦,好吧。

感谢您的回答/cmets。

【问题讨论】:

  • PHP 有一大堆这些奇怪的行为... :/ 手册说“在静态 context 中调用不可访问的方法时会触发 __callStatic”,这表明这可能是预期的行为。但这当然没有多大意义。这完全违反直觉
  • callMe 是一个非静态函数(在对象范围内),所以即使你调用了一个不存在的方法,你仍然在处理对象实例本身,所以很自然地会执行__call
  • 这很奇怪。如果您将self::bar(); 更改为foo::bar(),它仍将被非静态调用,即使这显然是一个静态调用。
  • @webbiedave, foo::bar() 显然不是静态调用。在类中调用像这样的非静态方法来准确指定在继承的情况下调用哪个方法是完全有效的。
  • @Matthew:你当然是对的。我的猫又敲键盘了。

标签: php


【解决方案1】:

在类方法的上下文中,您可能会对这些东西的含义感到困惑:

class B extends A {
  public function test() {
    A::foo();
    self::foo();
    static::foo();
  }
}

None 表示“调用名为 foo 的静态方法”。它只是表示在继承树中由冒号左侧指定的位置“调用名为 foo 的方法”。

通常,没有魔法,你只有一个名为foo的函数,所以意思很简单。然而,当你用 both 魔法方法重载时,调用是 ambiguous。 PHP 默认在__callStatic() 之前使用__call()

【讨论】:

    【解决方案2】:

    静态方法,变量属于类而不是对象,所以我认为这应该像这样工作。

    【讨论】:

    • 嗯?你能再解释一下吗?我没有看到连接
    • 一些解释:en.wikipedia.org/wiki/…
    • 你不需要向解释。那么,再一次,你为什么认为它应该这样工作?
    • 我的错。 inhand 已经解释了这种行为的主要概念。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多