【问题标题】:PHP sibling classes static bindingPHP 兄弟类静态绑定
【发布时间】:2012-04-03 08:30:04
【问题描述】:

在扩展同一个父类的多个类中自动加载时,它们似乎会覆盖彼此的静态变量。

使用下面的代码,如果$staticvar 仅在父类Controller 中定义,那么Foo::$staticvar 将被后续调用的同样扩展Controller 的类覆盖。

如果 Foo 本身也定义了$staticvar = null;,那么它不会被覆盖。这是为什么呢?


System.php

class System {
    static function load() {
        spl_autoload_register('System::autoload_controller');
        $classes = array('Foo', 'Bar', 'Test');
        foreach ($classes as $name) {
            $instance = new $name;
        }
    }

    static function autoload_controller($name) {
        echo $name.":\n";
        require_once strtolower($name).'.php';
        $name::$staticvar = 'static_'.$name;

        echo "Foo is: ".Foo::$staticvar."\n";
        echo $name." is: ".$name::$staticvar."\n\n";
    }
}

class Controller {
    static $staticvar = null;
}

System::load();

如果 foo.php 是这样的:

class Foo extends Controller {

}

我得到了输出:

Foo:
Foo is: static_Foo
Foo is: static_Foo

Bar:
Foo is: static_Bar
Bar is: static_Bar

Test:
Foo is: static_Test
Test is: static_Test

但是如果我把 foo.php 改成这样:

class Foo extends Controller {
    static $staticvar = null;
}

我得到了输出:

Foo:
Foo is: static_Foo
Foo is: static_Foo

Bar:
Foo is: static_Foo
Bar is: static_Bar

Test:
Foo is: static_Foo
Test is: static_Test

【问题讨论】:

  • 行为是正确的,当继承一个静态变量时,这意味着父类的所有实例和后代共享实际的相同变量,所以如果一个实例改变了变量值,它似乎被改变了或在所有情况下“覆盖”,因为它是共享的同一个变量。

标签: php static-binding


【解决方案1】:

如果 Foo 本身也定义了 $staticvar = null;那么它不会被覆盖。这是为什么呢?

因为“静态”意味着它是静态的(绑定)到定义它的范围(类)。这意味着Controller::$staticvar 和Foo::$staticvar 是两个不同的 属性。

【讨论】:

  • 这是有道理的。有没有办法强制孩子拥有自己的静态变量版本,而不必在每种情况下都定义它?
  • “不定义”?那是“强制”它的方式:?
  • 没错,只是看起来他们没有正确继承,但我明白为什么会这样。谢谢。
猜你喜欢
  • 2015-08-28
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多