web-dev-qa-db-ja.com

新しい自己と新しい静的

PHP 5.3ライブラリをPHP 5.2で動作するように変換しています。私の邪魔をしている主なものはreturn new static($options);のような遅い静的バインディングの使用です。これをreturn new self($options)に変換しても同じ結果になりますか?

new selfnew staticの違いは何ですか?

463
Mike

同じ結果が得られますか?

あんまり。ただし、PHP 5.2の回避策はわかりません。

new selfnew staticの違いは何ですか?

selfは、newキーワードが実際に書かれているのと同じクラスを指します。

PHP 5.3の最新の静的バインディングに含まれるstaticは、階層内でメソッドを呼び出したすべてのクラスを参照します。

次の例では、Bは両方のメソッドをAから継承しています。 selfの呼び出しは、Aの最初のメソッドの実装で定義されているため、Aにバインドされます。一方、staticは、呼び出されるクラスにバインドされます( get_called_class() も参照)。

class A {
    public static function get_self() {
        return new self();
    }

    public static function get_static() {
        return new static();
    }
}

class B extends A {}

echo get_class(B::get_self());  // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A
806
BoltClock

このコードのメソッドが静的でない場合は、get_class($this)を使用して5.2で回避策をとることができます。

class A {
    public function create1() {
        $class = get_class($this);
        return new $class();
    }
    public function create2() {
        return new static();
    }
}

class B extends A {

}

$b = new B();
var_dump(get_class($b->create1()), get_class($b->create2()));

結果:

string(1) "B"
string(1) "B"
18

他の人の答えに加えて:

static ::は実行時情報を使って計算されます。

つまり、static::をクラスプロパティで使用することはできません。

コンパイル時に評価できなければならず、実行時情報に依存してはいけません。

class Foo {
    public $name = static::class;

}

$Foo = new Foo;
echo $Foo->name; // Fatal error

self::を使う

class Foo {
    public $name = self::class;

}
$Foo = new Foo;
echo $Foo->name; // Foo
5
FatalError