【发布时间】: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