2012-01-18 11 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

+1

を[正常に動作するようです](http://codepad.viper-7.com/BlBDGC)。 – cmbuckley

答えて

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

をインスタンスを保持するために配列を必要とせず、代わりにサブクラスを保持させます。以下のコードを試してみてください。

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を取得するときにC1を取得します:: getInstance(); – CSharpRU

+0

@ user1155760コードパッドが見えましたか?私はあなたのコードをコピーしてC2を取得しました。 – xdazz

+0

はい、ただしローカルにはまだC1があります。 – CSharpRU

2

これが機能しない理由は、各サブクラスごとに$ instanceプロパティを作成していないからです。 static ::およびget_called_class()を使用すると、スーパークラスメンバの代わりにサブクラスメンバにアクセスしますが、メンバがサブクラスに存在しない場合は、スーパークラスで定義されたメンバにフォールバックします。とにかく同じメンバーを得ることになります。

このようにサブクラスを定義してみてください。

class C1 extends Singleton { 
    protected static $instances; 
} 

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

この抽象シングルトン試してみてください::

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

The code

を更新する必要があります

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

0

私はあなたの問題を再現することはできません。

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

が与える:var_dump出力が示すよう

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

を、種類は(C1、その後、C2)異なっています。 getInstance()は静的関数なので静的に呼び出す必要があることに注意してください。

次に、PHPで実際にシングルトンパターンを実装する場合、抽象クラスには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