2012-01-18 84 views
0

我有最後的靜態方法 「的getInstance()」 單例類:PHP 5.3抽象單身班和兒童?

<?php 

abstract class Singleton 
{ 
    protected static $instances; 

    final public static function getInstance() 
    { 
     $class = get_called_class(); 

     if(!isset(static::$instances[$class])) 
      static::$instances[$class] = new $class(); 

     return static::$instances[$class]; 
    } 
} 

而且這樣的代碼:

<?php 

class C1 extends Singleton { } 
class C2 extends Singleton { } 

C1::getInstance(); // Created C1 class 
C2::getInstance(); // Still get C1 class, get_called_class() return C1 when i try get C2 

什麼我做錯了什麼?

+5

您使用的一個開始:) – GordonM 2012-01-18 08:58:38

+1

單身[看起來工作得很好(http://codepad.viper-7.com/BlBDGC)。 – cmbuckley 2012-01-18 09:20:01

回答

1
C1->getInstance(); 
C2->getInstance(); 

應該

C1::getInstance(); 
C2::getInstance(); 

The code

更新: 您不需要一個數組來保存實例,而是讓子類保持。嘗試下面的代碼。

class Singleton 
{ 
    private function __construct(){} 

    protected static $instance; 

    final public static function getInstance() 
    { 
     $class = get_called_class(); 
     if(!static::$instance) 
      static::$instance = new $class(); 

     return static::$instance; 
    } 
} 

class C1 extends Singleton { 
    protected static $instance; 
} 
class C2 extends Singleton { 
    protected static $instance; 
} 

var_dump(C1::getInstance()); 
var_dump(C2::getInstance()); 
+0

對不起,我的錯。無論如何,當我調用C2 :: getInstance()時,我還是得到了C1。 – CSharpRU 2012-01-18 09:17:32

+0

@ user1155760您是否看到了鍵盤?我只是複製你的代碼並獲得C2。 – xdazz 2012-01-18 09:22:01

+0

是的,但本地仍然獲得C1。 – CSharpRU 2012-01-18 09:23:43

2

這不起作用的原因是你沒有爲你的每個子類創建一個$ instance屬性。雖然使用static ::和get_called_class()將訪問子類成員而不是超類成員,但如果成員不存在於子類中,則它們將回退到超類中定義的成員。這樣做的結果就是你最終會得到同樣的成員。

嘗試像這樣定義你的子類。

class C1 extends Singleton { 
    protected static $instances; 
} 

class C2 extends Singleton { 
    protected static $instances; 
} 
1

試試這個抽象辛格爾頓:

abstract class Singleton 
{ 
    private static $_instances = array(); 

    public static function getInstance() 
    { 
     $class = get_called_class(); 
     if (!isset(self::$_instances[$class])) { 
      self::$_instances[$class] = new $class(); 
     } 
     return self::$_instances[$class]; 
    } 
} 
+0

+1'self'關鍵字在這裏更有意義。 – cmbuckley 2012-01-18 09:22:48

0

我無法重現你的問題:

var_dump(C1::getInstance()); 
var_dump(C2::getInstance()); 

給出:

object(C1)#1 (0) { 
} 
object(C2)#2 (0) { 
} 

由於var_dump輸出顯示,類型不同(C1,然後C2)。請記住,您需要靜態調用getInstance(),因爲它是一個靜態函數。

接下來,如果你想真正在PHP中實現Singleton模式,那麼你的抽象類缺少一些重要的方法定義,以便使用PHP更加精確。請參閱Patterns­PHP Manual

另外在PHP中,你通常不需要單例,而是注入依賴,這會使你的代碼更加流暢。

希望這是有幫助的。

0

工作抽象單的版本:

abstract class Singletone { 
    private static $_instance = NULL; 

    private function __construct(){} 

    public static function GetInstance() { 

     if(!static::$_instance) { 
      static::$_instance = new static(); 
     } 
     return static::$_instance; 
    } 
} 

派生類必須覆蓋$ _instance

class DefaultRouter extends Singletone { 
    protected static $_instance = NULL; 
} 
0

有沒有必要重新定義靜態的$instance屬性的子類,只需要使用一個定義在超類中:

<?php 
class Singleton 
{ 
    public static $Instance; 

    private function __construct() { } 

    public static function GetInstance() { 

     if(!Singleton::$Instance) { 
      Singleton::$Instance = new static(); 
     } 
     return Singleton::$Instance; 
    } 
} 

class MyClass extends Singleton 
{ 
    public $field1; 
    public $field2; 
    public $field3; 

    public function __construct() 
    { 
     $this->field1 = "field1"; 
     $this->field2 = "field2"; 
     $this->field3 = "field3"; 
    } 
} 

var_dump(Myclass::GetInstance()); 
?> 

它輸出

object(MyClass)#1 (3) { 
    ["field1"]=> 
    string(6) "field1" 
    ["field2"]=> 
    string(6) "field2" 
    ["field3"]=> 
    string(6) "field3" 
} 

https://eval.in/306503