web-dev-qa-db-ja.com

new self()とは何ですか? PHPではどうですか?

私はこのようなコードを見たことがない:

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

new className()と同じですか?

[〜#〜] edit [〜#〜]

クラスが継承クラスである場合、どのクラスを指しますか?

103
user198729

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) { } 
_

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


2番目の状況では、コードは次のようになります。

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

}

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

そして、このような出力が得られます:

_object(MyParentClass)#1 (0) { }
_

つまり、selfMyParentClassを意味します-つまり、ここでも書き込まれたクラスです。




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 ページをご覧ください。

199
Pascal MARTIN

これは Singleton pattern の実装のようです。この関数は静的に呼び出され、静的クラスに変数_$_instance_が設定されているかどうかを確認します。

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

className::getInstance()を呼び出すと、すべての呼び出しでoneおよびsameクラスインスタンスが得られます。これはシングルトンパターンのポイントです。

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

9
Pekka 웃

これはおそらく、インスタンス化されないようにコンストラクタがプライベートとして定義されているシングルトンデザインパターンで使用される可能性が高く、二重コロン_(::)_演算子はクラス内で静的と宣言されたメンバーにアクセスできるため、静的メンバー、擬似変数$ 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();
_

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

7
flimh

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

2
Matteo Riva

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

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

0
kta