2012-07-14 124 views
1

我想了解PHP如何用擴展類中的靜態方法管理內存和變量。我有三個名爲Model,User1,User2的類。因此:擴展類和靜態值

class Model { 
    static public $structure; 
    static public $name; 
    static function get_structure() { 
     return self::$structure = file_get_contents(self::$name.'.json'); 
    } 
} 
class User1 extends Model { 

} 
class User2 extends Model { 

} 
User1::$name = 'User1'; 
User2::$name = 'User2'; 
echo User1::get_structure(); 
echo User2::get_structure(); 

如果我運行User1 :: get_structure();由於某種原因,它不能相應地填充結果,它似乎在抓取User2的值(聲明的最後一個$ name值)。

我正在假設聲明User2和擴展模型爲我的$ name屬性創建一個完全獨立的作用域。因此,User1和User2被聲明爲具有與Model相同結構的獨立類。然後我可以在不同的範圍內爲它們靜態地定義它們的值。

但我現在在質疑。如果我擴展並調用相同的$ name變量,它們是否都指向Model類?或者當我使用新的User1()聲明每個類時,它只創建一個單獨的範圍;和新的User2();?

謝謝。

+0

如果使用的是靜態類,它不是面向對象編程。我正在移除標籤。此外,模型是[層](http://stackoverflow.com/a/5864000/727208),而不是一個類。 – 2012-07-14 17:37:17

+0

... rriigghhtt。好吧。 – pilotguy 2012-07-14 17:42:08

回答

1

你遇到這個問題,因爲你正在訪問相同的變量

class X 
{ 
    public static $data = null; 
} 

class Foo extends X{}; 
class Bar extends X{}; 

Foo::$data = 'lorem ipsum'; 
echo Bar::$data; 
// :: output :: lorem ipsum; 

$name變量撐綁Model類,即使是在繼承的類。

+0

非常好,這確切地證實了我的想法。謝謝。 – pilotguy 2012-07-14 17:53:43

+0

@pilotguy,我實際上會建議你儘量避免使用靜態變量。類中的靜態變量就像命名空間'global'一樣。雖然語法已更改,但它們具有與[全局狀態](http://www.youtube.com/watch?v=-FRm3VPhseI)相關的相同行爲和相同問題。 – 2012-07-14 17:58:36

0

你可以解決它:

<?php 
class Model { 
    static public $structure; 
    static public $name; 
    static function get_structure() { 
     $class = get_called_class(); 
     return $class::$structure = file_get_contents($class::$name.'.json'); 
    } 
} 
class User1 extends Model { 
    static public $structure; 
    static public $name; 
} 
class User2 extends Model { 
    static public $structure; 
    static public $name; 
} 
User1::$name = 'User1'; 
User2::$name = 'User2'; 
echo User1::get_structure(); 
echo User2::get_structure(); 

...但是,你可能會問自己這樣的設計是正確的一個。 atm它看起來像它們應該是具有不同值的實例&實例方法,但這可能是因爲精簡的例子。

+0

嗯,這是一個不錯的主意。我的目標是不要強制用戶實例化模型層,直到他們必須完成。這是爲了便於編碼+我敢打賭,我可以爭辯說,它對性能也很好。我正在考慮一個模型只是一個適配器到數據庫......我所有返回的數據集都是指向模型的特定於框架的「記錄」對象。 – pilotguy 2012-07-15 12:46:08

1

是的,所有延伸型號的類都將指向相同的$ name變量。 將靜態變量看作「全局」變量。

也許這個例子來闡明你:

class Model 
{ 
    static public $name; 
} 

class User1 extends Model 
{ 
    public function setName($name) 
    { 
     parent::$name = $name; 
    } 

    public function getName() 
    { 
     return parent::$name; 
    } 
} 

class User2 extends Model 
{ 
    public function setName($name) 
    { 
     parent::$name = $name; 
    } 

    public function getName() 
    { 
     return parent::$name; 
    } 
} 

$user1 = new User1(); 
$user1->setName("User1"); 

$user2 = new User2(); 
$user1->setName("User2"); 

echo $user1->getName(); 
echo $user2->getName(); 

// Output : User2User2