2012-04-03 71 views
1

當自動加載多個擴展同一個父類的類時,它們似乎會覆蓋其他每個靜態變量。PHP兄弟類靜態綁定

使用下面的代碼,如果$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 
+0

當繼承一個靜態變量時,它的行爲是正確的,這意味着父類和子孫的所有實例共享實際的SAME變量,因此如果實例更改變量值,它似乎被更改或「覆蓋」在所有的實例,因爲它是共享相同的變量。 – Yaniro 2012-04-03 08:38:34

回答

4

然而,如果Foo自己也定義$ staticVar中= NULL ;那麼它不會被覆蓋。爲什麼是這樣?

因爲「靜態」是指靜態(綁定)到它定義的範圍(類)。這意味着Controller::$staticvarFoo::$staticvar是兩個不同的屬性。

+0

這很有道理。是否沒有辦法強制孩子們擁有他們自己的靜態變量版本,而不必在每種情況下定義它們? – 2012-04-03 08:54:36

+0

「沒有定義它」?這是「強制」它的方式:? – KingCrunch 2012-04-03 08:57:09

+0

沒錯,它看起來好像沒有正確繼承,但我可以看出爲什麼它是這樣的。謝謝。 – 2012-04-03 09:02:01