120

私はこのようなコードを見たことがありません:

public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}

と同じnew className()ですか?

編集

クラスが継承されている場合、どのクラスを指しますか?

4

5 に答える 5

229

selfそれが書かれているクラスを指します。

したがって、getInstanceメソッドがクラス名に含まれているMyClass場合、次の行になります。

self::$_instance = new self();

と同じことをします:

self::$_instance = new MyClass();


編集:コメントの後、もう少し情報。

相互に拡張する2つのクラスがある場合、2つの状況があります。

  • getInstance子クラスで定義されています
  • getInstance親クラスで定義されています

最初の状況は次のようになります(この例では、不要なコードをすべて削除しました。シングルトンの動作を取得するには、コードを追加し直す必要があります)*:

class MyParentClass {
    
}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

ここでは、次のようになります。

object(MyChildClass)#1 (0) { } 

つまり、つまり、それが記述されているクラスをself意味します。MyChildClass


2番目の状況では、コードは次のようになります。
class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {
    
}

$a = MyChildClass::getInstance();
var_dump($a);

そして、あなたはこの種の出力を得るでしょう:

object(MyParentClass)#1 (0) { }

つまり、selfつまりMyParentClass、ここでも、それが記述されているクラスを意味します。




PHPを使用する場合PHP5.3ではキーワードの新しい使用法が導入されています。これらの例staticで使用した場所で正確に使用できるようになりました。self

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {
    
}

$a = MyChildClass::getInstance();
var_dump($a);

しかし、のstatic代わりにself、次のようになります。

object(MyChildClass)#1 (0) { } 

つまり、ある種は、それが書かれているクラスではなく、使用されている(私たちが使用した)クラスをstatic指しているということです。MyChildClass::getInstance()

もちろん、self既存のアプリケーションを壊さないように、の動作は変更されていません。PHP5.3は、staticキーワードをリサイクルして新しい動作を追加しただけです。


また、PHP 5.3については、PHPマニュアルの[Late StaticBindings][1]ページをご覧ください。
于 2010-03-07T13:41:32.213 に答える
10

これは、シングルトンパターンの実装のようです。この関数は静的に呼び出され、静的クラスに変数$_instanceが設定されているかどうかを確認します。

そうでない場合は、それ自体のインスタンス(new self())を初期化し、に格納し$_instanceます。

呼び出すと、すべての呼び出しで同じclassName::getInstance()クラスインスタンスが取得されます。これが、シングルトンパターンのポイントです。

しかし、これがこのように行われるのを見たことがなく、正直なところ、それが可能であるとは知りませんでした。クラスで何が$_instance宣言されていますか?

于 2010-03-07T13:41:59.017 に答える
7

これはシングルトン設計パターンで使用される可能性が最も高く、コンストラクターはインスタンス化を避けるためにプライベートとして定義され、二重コロン(::)演算子はクラス内で静的に宣言されたメンバーにアクセスできるため、静的メンバーがある場合、疑似変数 $これは使用できないため、コードでは代わりに self を使用しました。Singleton は、データベース コネクタ ハンドラのようなオブジェクトの 1 つのインスタンスのみを許可する優れたプログラミング プラクティスです。クライアントコードから、そのインスタンスへのアクセスは、単一のアクセスポイントを作成することによって行われます.この場合、彼はそれに名前を付けましgetInstance()た.とも呼ばれている。

if(!isset(self::instance))は、オブジェクトが既に作成されているかどうかをチェックします。コードが単なるフラグメントであるため、これを理解できませんでした。上部のどこかに、おそらく次のような静的メンバーがあるはずです。

private static $_instance = NULL; 

通常のクラスでは、単純にこのメンバーにアクセスします

$this->_instance = 'something';

しかし、静的に宣言されているため、代わりに使用する $this コードを使用できませんでした

self::$_instance

この静的クラス変数にオブジェクトが格納されているかどうかを確認することにより、クラスは単一のインスタンスを作成するか作成しないかを決定できます。そのため、インスタンスが設定されていない場合、!isset、つまり静的メンバー $_instance にオブジェクトが存在しないことを意味します。新しいオブジェクトを生成$_instanceし、コマンドによって静的メンバーに格納します

self::$_instance = new self();

そしてそれをクライアントコードに返しました。その後、クライアント コードはオブジェクトの単一のインスタンスをそのパブリック メソッドで問題なく使用できますが、クライアント コードでは、単一のアクセス ポイントを呼び出します。つまり、getInstance()メソッドもトリッキーです。このように呼び出す必要があります。

$thisObject = className::getInstance();

その理由は、関数自体が静的に宣言されているためです。

于 2010-11-25T05:25:34.263 に答える
2

はい、それはnew className()(そのメソッドを含むクラスを参照して)似ており、おそらくコンストラクターがプライベートであるシングルトンパターンで使用されます。

于 2010-03-07T13:41:40.840 に答える
0

クラスが継承されている場合、子から getInstance() を呼び出しても子のインスタンスは得られません。親インスタンスのインスタンスのみを返します。これは、new self() を呼び出すためです。

子クラスが子クラスのインスタンスを返すようにしたい場合は、getInstance() で new static() を使用すると、子クラスのインスタンスが返されます。これは遅延バインディングと呼ばれます!!

于 2015-09-27T07:20:12.960 に答える