私はこのようなコードを見たことがない:
_public static function getInstance()
{
if ( ! isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
_
new className()
と同じですか?
[〜#〜] edit [〜#〜]
クラスが継承クラスである場合、どのクラスを指しますか?
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 <5.3では、「それが記述されているクラス」は重要であり、時には問題を引き起こす可能性があります。
PHP 5.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
の動作は、既存のアプリケーションを壊さないように変更されていません-PHP 5.3は、static
キーワードをリサイクルする新しい動作を追加しました。
そして、PHP 5.3については、PHPマニュアルの Late Static Bindings ページをご覧ください。
これは Singleton pattern の実装のようです。この関数は静的に呼び出され、静的クラスに変数_$_instance
_が設定されているかどうかを確認します。
そうでない場合、自身のインスタンス(new self()
)を初期化し、_$_instance
_に格納します。
className::getInstance()
を呼び出すと、すべての呼び出しでoneおよびsameクラスインスタンスが得られます。これはシングルトンパターンのポイントです。
しかし、これがこのように行われるのを見たことはなく、正直に、それが可能であることを知りませんでした。クラスで宣言されている_$_instance
_とは何ですか?
これはおそらく、インスタンス化されないようにコンストラクタがプライベートとして定義されているシングルトンデザインパターンで使用される可能性が高く、二重コロン_(::)
_演算子はクラス内で静的と宣言されたメンバーにアクセスできるため、静的メンバー、擬似変数$ thisは使用できないため、コードは代わりにselfを使用します。シングルトンは、データベースコネクタハンドラーのようなオブジェクトの1つのインスタンスのみを許可する優れたプログラミング手法です。クライアントコードから、そのインスタンスへのアクセスは、単一のアクセスポイントを作成することによって行われます。この場合、彼はgetInstance()
という名前を付けました。getInstance自体は、基本的にnewキーワードを使用してオブジェクトを作成した関数コンストラクターメソッドを意味するオブジェクトも呼び出されました。
if(!isset(self::instance))
行は、オブジェクトがすでに作成されているかどうかをチェックします。コードは単なるフラグメントであるため、このコードを理解できませんでした。
_private static $_instance = NULL;
_
通常のクラスでは、単にこのメンバーにアクセスします
_$this->_instance = 'something';
_
しかし、宣言された静的なので、代わりに使用する$ thisコードを使用できませんでした
_self::$_instance
_
この静的クラス変数にオブジェクトが保存されているかどうかを確認することで、クラスは単一のインスタンスを作成するか作成しないかを決定できるので、設定されていない場合は!新しいオブジェクトを生成し、コマンドによって静的メンバー_$_instance
_に格納します
_self::$_instance = new self();
_
それをクライアントコードに返しました。クライアントコードは、そのパブリックメソッドでオブジェクトの単一のインスタンスを喜んで使用できますが、クライアントコードでは、単一のアクセスポイントを呼び出す、つまりgetInstance()
メソッドもトリッキーです。こう呼ばれる
_$thisObject = className::getInstance();
_
その理由は、関数自体が静的であると宣言されているためです。
はい、それはnew className()
(そのメソッドを含むクラスを参照)のようなもので、おそらくコンストラクターがプライベートなシングルトンパターンで使用されます。
クラスが継承されている場合、子からgetInstance()を呼び出しても子のインスタンスは得られません。親インスタンスのインスタンスのみを返します。これは、新しいself()を呼び出すためです。
子クラスが子クラスのインスタンスを返すようにする場合は、getInstance()で新しいstatic()を使用してから、子クラスのインスタンスを返します。これは遅延バインディングと呼ばれます!!