回答:
を使用self
してクラスメンバーを参照する場合は、キーワードを使用するクラスを参照しています。この場合、Foo
クラスはと呼ばれる保護された静的プロパティを定義します$bar
。あなたは、使用するときself
にFoo
プロパティを参照するクラスは、同じクラスを参照しています。
したがってself::$bar
、Foo
クラスの別の場所で使用しようとしたがBar
、プロパティの値が異なるクラスがある場合は、Foo::$bar
ではなくを使用しますがBar::$bar
、これは意図したものではない可能性があります。
class Foo
{
protected static $bar = 1234;
}
class Bar extends Foo
{
protected static $bar = 4321;
}
あなたはときに呼び出しを経由する方法をstatic
、あなたはと呼ばれる機能を呼び出すしている遅延静的バインディングを(PHP 5.3で導入を)。
上記のシナリオでは、使用self
するとFoo::$bar
(1234)になります。を使用static
すると、結果はBar::$bar
(4321)になります。これはstatic
、インタープリターが内の再宣言を考慮に入れるためです。Bar
になります。実行時にクラスです。
通常、サブクラスでプロパティを再宣言しないため、プロパティではなく、メソッドまたはクラス自体にレイトスタティックバインディングを使用します。static
遅延バインディングコンストラクターを呼び出すためのキーワードの使用例は、この関連質問にあります。新しい自己vs.新しい静的
ただし、これはstatic
プロパティでの使用も排除していません。
<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
self::$abc
、内部class Foo
で使用する場合はと同じFoo::$abc
です。$abc
サブクラスでのの再宣言の影響を受けません。AFAIKを使用する唯一の理由self
は、クラス名を使用しないようにするための省略形Foo
です。[これらのすべての場所を変更せずにクラス名を変更できることも意味しますが、それがIMHOの理由の多くではありません。](PHPの名前の選択は残念であり、逆のように見えます。自然言語の単語「静的」の口語的な意味とは逆です。)
前述のように、主な違いの1つは、static
遅延静的バインディングを可能にすることです。私が見つけた最も有用なシナリオの1つは、シングルトンクラスの基本クラスを作成するためのものです。
class A { // Base Class
protected static $name = '';
protected static function getName() {
return static::$name;
}
}
class B extends A {
protected static $name = 'MyCustomNameB';
}
class C extends A {
protected static $name = 'MyCustomNameC';
}
echo B::getName(); // MyCustomNameB
echo C::getName(); // MyCustomNameC
return static::$name
Baseクラスで使用すると、拡張時に静的にアタッチされたものが返されます。あなたが使用した場合return self::$name
、その後B::getName()
それは基本クラスで宣言されたものであるとして、空の文字列を返します。
self
コール:
class Foo
{
protected static $var = 123;
public function getVar()
{
return self::$var;
}
}
class Bar extends Foo
{
protected static $var = 234;
}
// Displays: "123"
echo (new Bar)->getVar();
上記のように、クラスでをオーバーライドしました$var
が、PHPに変数を明示的に要求したため、Bar
123
self
Foo
代わり s変数を。
ここで、呼び出しをと交換するとstatic
、代わりにBar
上書きされた値がされます。
static
コール:
class Foo
{
protected static $var = 123;
public function getVar()
{
return static::$var;
}
}
class Bar extends Foo
{
protected static $var = 234;
}
// Displays: "234"
echo (new Bar)->getVar();