4
<?php
class A {
  public function instanceFunc() {
    echo "instance";
  }

  public static function staticFunc() {
    echo "static";
  }
}

A::instanceFunc(); // instance
$a = new A();
$a->staticFunc(); // static

这意味着 PHP 中的静态方法和实例方法完全没有区别。Zend 甚至没有抱怨它(没有警告)。

在 Zend 引擎中。静态方法和实例方法都保存在 zend_class_entry.function_table 中。

为什么 PHP 会这样?这是一个错误或功能?

4

3 回答 3

3

这是PHP 中的静态方法与非静态方法有什么区别的潜在副本吗?.

如果您启用了 E_STRICT 警告,您将收到一条错误消息,否则,您可以静默调用非静态方法,就好像它是静态的一样。正如此处和另一个问题的答案中所提到的,如果没有访问$thisself按照预期编写

参考文档: http ://www.php.net/manual/en/language.oop5.static.php

这里有一些东西可以玩:

http://codepad.org/Gbu9T6Zv

于 2011-04-19T17:35:56.487 回答
2

如果您尝试运行下面的代码并查看回溯输出,您将看到 PHP 在静态上下文中调用时将 instanceFunc() 转换为静态方法。但是,在实例上下文中,它会将其视为实例调用。

如果您在混合中引入实例变量(删除注释掉的行),那么从静态调用调用 instanceFunc() 时会遇到致命错误。

这意味着 PHP 允许从静态上下文中调用所有本质上是静态的方法(不使用实例变量),但一旦该合约被破坏,就会产生错误。因此,使用静态函数似乎只是与其他面向对象语言保持一致的好习惯。

关于 staticFunc() 两个调用都表明 PHP 将它们解释为静态调用,这是意料之中的。

class A {
  private $x = 5;
  private $y = 6;
  private $z;
  public function instanceFunc() {
    //$this->z = $this->y * $this->x;
    //echo $this->z;
    var_dump(reset(debug_backtrace()));
  }

  public static function staticFunc() {
    var_dump(reset(debug_backtrace()));
  }
}
$a = new A();
A::instanceFunc(); // static call of intended instance method
$a->instanceFunc(); // instance call of instance method
A::staticFunc();
$a->staticFunc();

示例输出(使用注释运行的代码):

array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(19) ["function"]=>  string(12) "instanceFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=>  array(0) { } } 
array(7) { ["file"]=> string(59) "test.php" ["line"]=> int(22) ["function"]=> string(12) "instanceFunc" ["class"]=> string(1) "A" ["object"]=> object(A)#8 (3) { ["x:private"]=> int(5) ["y:private"]=> int(6) ["z:private"]=> NULL } ["type"]=> string(2) "->" ["args"]=> array(0) { } } 
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(24) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } } 
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(26) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } }
于 2011-04-19T17:49:41.390 回答
1

我不确定为什么它不会引发警告或至少不会引发错误。但是,静态和实例存在一些主要差异。静态方法不能使用非静态的类变量。通过添加一个非静态的公共/私有变量并尝试在其中回显它staticFunc会引发错误,这很容易测试。

我认为主要目标是了解两者之间的差异以及如何正确使用它们。至于为什么 PHP 至少没有发出通知,我不知道,也许是由于它的悠闲性质。我对有更多知识的人可以给出的回应感兴趣,这只是一些额外的信息。

我确实使用完整的错误报告对其进行了测试,果然它确实没有发出通知或警告。


更新

做一些测试,似乎当您将未标记的静态函数调用为静态函数时,您仍然无法使用私有/公共变量。对于正常功能,这很可能会出错。这可能就是为什么从未抛出错误或通知的原因。但是,它最好抛出一些东西,因为以这种方式使用未标记的静态函数肯定不好。

于 2011-04-19T17:23:12.160 回答