self
PHP 5では、とを使用することの違いは何$this
ですか?
それぞれが適切なのはいつですか?
$this
現在のオブジェクトを参照するために使用します。self
現在のクラスを参照するために使用します。つまり、$this->member
非静的メンバーに使用self::$member
し、静的メンバーに使用します。
非静的および静的メンバー変数のおよびの正しい使用例を次に示します。$this
self
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
非静的および静的メンバー変数のおよびの誤った使用例を次に示します。$this
self
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo self::$non_static_member . ' '
. $this->static_member;
}
}
new X();
?>
これは、メンバー関数のポリモーフィズムの例です。$this
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
$this->foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
これは、 forメンバー関数を使用してポリモーフィックな動作を抑制する例です。self
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
self::foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
アイデアは、現在のオブジェクトの正確なタイプが何であれ、メンバー関数を
$this->foo()
呼び出すことです。foo()
オブジェクトがの場合、type X
したがって。を呼び出しますX::foo()
。オブジェクトがの場合、type Y
を呼び出しますY::foo()
。ただし、self :: foo()を使用するX::foo()
と、常に呼び出されます。
http://www.phpbuilder.com/board/showthread.php?t=10354489から:
キーワードselfは、少なくとも静的メンバーに制限する方法ではなく、単に「現在のクラス」を参照するものではありません。非静的メンバーのコンテキスト内で、現在のオブジェクトの vtable ( vtable に関する wiki を参照self
)をバイパスする方法も提供します。関数の親バージョンを呼び出すために使用できるのと同じように、メソッドの現在のクラス実装を呼び出すために呼び出すことができます。parent::methodName()
self::methodName()
class Person {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function getTitle() {
return $this->getName()." the person";
}
public function sayHello() {
echo "Hello, I'm ".$this->getTitle()."<br/>";
}
public function sayGoodbye() {
echo "Goodbye from ".self::getTitle()."<br/>";
}
}
class Geek extends Person {
public function __construct($name) {
parent::__construct($name);
}
public function getTitle() {
return $this->getName()." the geek";
}
}
$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();
これは出力されます:
こんにちは、オタクのルートヴィヒです
人間のルートヴィヒからさようなら
sayHello()
は$this
ポインターを使用するため、 vtable が呼び出されて が呼び出されますGeek::getTitle()
。
sayGoodbye()
を使用するself::getTitle()
ため、vtable は使用されず、Person::getTitle()
呼び出されます。どちらの場合も、インスタンス化されたオブジェクトのメソッドを扱っており$this
、呼び出された関数内のポインターにアクセスできます。
使用しないでください self::
。使用static::
*
self:: には、言及する価値のある別の側面があります。厄介なself::
ことに、実行時点ではなく、定義時点でのスコープを参照します。次の 2 つのメソッドを持つ単純なクラスを考えてみましょう。
class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
呼び出すPerson::status()
と、「Person is alive」と表示されます。これから継承するクラスを作成するとどうなるかを考えてみましょう。
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
電話Deceased::status()
すると、「人が死亡しました」と表示されることが期待されます。ただし、スコープには呼び出しself::getStatus()
が定義されたときの元のメソッド定義が含まれているため、「Person is alive」と表示されます。
PHP 5.3 には解決策があります。解決演算子はstatic::
、呼び出されたクラスのスコープにバインドされていることを示す派手な方法である「遅延静的バインディング」を実装します。行を に変更するstatus()
とstatic::getStatus()
、期待どおりの結果が得られます。古いバージョンの PHP では、これを行うには kludge を見つける必要があります。
PHP ドキュメントを参照してください
だから、尋ねられたのではない質問に答えるために...
$this->
クラスを参照するのに対し、現在のオブジェクト (クラスのインスタンス) をstatic::
参照します。
self
対について話すときに何について話しているのかを本当に理解するに$this
は、概念的および実際的なレベルで何が起こっているのかを実際に掘り下げる必要があります。どの答えもこれを適切に行っているとは思えないので、これが私の試みです。
クラスとオブジェクトが何であるかについて話すことから始めましょう。
それで、クラスとは何ですか?多くの人がオブジェクトの青写真またはテンプレートとして定義しています。実際、 About Classes In PHP Hereの詳細を読むことができます。そして、ある意味でそれは本当です。クラスを見てみましょう:
class Person {
public $name = 'my name';
public function sayHello() {
echo "Hello";
}
}
おわかりのように、そのクラスには と呼ばれるプロパティと$name
と呼ばれるメソッド (関数) がありsayHello()
ます。
クラスが静的構造であることに注意することは非常に重要です。つまり、一度定義された classは、どこから見ても常に同じです。Person
一方、オブジェクトはクラスのインスタンスと呼ばれるものです。つまり、クラスの「設計図」を取得し、それを使用して動的コピーを作成します。このコピーは、それが格納されている変数に明確に関連付けられるようになりました。したがって、インスタンスへの変更はそのインスタンスに対してローカルです。
$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"
演算子を使用して、クラスの新しいインスタンスを作成します。new
したがって、クラスはグローバル構造であり、オブジェクトはローカル構造であると言います。->
おかしな構文について心配する必要はありません。これについては後で詳しく説明します。
もう 1 つお話ししなければならないことは、インスタンスが特定のクラスであるかどうかを確認できることです。これは、インスタンスがクラスを使用して作成された場合、またはの子である場合はブール値を返します。instanceof
$bob instanceof Person
$bob
Person
Person
それでは、クラスに実際に含まれているものを少し掘り下げてみましょう。クラスに含まれる「もの」には、次の 5 種類があります。
プロパティ- これらは、各インスタンスに含まれる変数と考えてください。
class Foo {
public $bar = 1;
}
静的プロパティ- これらは、クラス レベルで共有される変数と考えてください。つまり、各インスタンスによってコピーされることはありません。
class Foo {
public static $bar = 1;
}
メソッド- これらは、各インスタンスに含まれる (およびインスタンスで動作する) 関数です。
class Foo {
public function bar() {}
}
静的メソッド- クラス全体で共有される関数です。これらはインスタンスでは機能せず、代わりに静的プロパティのみで機能します。
class Foo {
public static function bar() {}
}
定数- クラス解決定数。ここではこれ以上深く掘り下げませんが、完全を期すために追加します。
class Foo {
const BAR = 1;
}
したがって、基本的には、情報が共有されている (したがって静的) か共有されていない (したがって動的) かを識別する静的に関する「ヒント」を使用して、クラスおよびオブジェクト コンテナーに情報を格納しています。
メソッド内では、オブジェクトのインスタンスは変数によって表され$this
ます。そのオブジェクトの現在の状態がそこにあり、任意のプロパティを変更 (変更) すると、そのインスタンスが変更されます (他のインスタンスは変更されません)。
メソッドが静的に呼び出された場合、$this
変数は定義されていません。これは、静的呼び出しに関連付けられたインスタンスがないためです。
ここで興味深いのは、静的呼び出しがどのように行われるかです。それでは、状態にアクセスする方法について話しましょう。
その状態を保存したので、それにアクセスする必要があります。これは少しトリッキーになる可能性があるため (または少し複雑になる可能性があります)、インスタンス/クラスの外側 (通常の関数呼び出しまたはグローバル スコープなど) とインスタンスの内側の 2 つの視点に分けて考えてみましょう。 /class (オブジェクトのメソッド内から)。
インスタンス/クラスの外側から見ると、ルールは非常に単純で予測可能です。2 つの演算子があり、それぞれがインスタンスまたはクラス static を扱っているかどうかをすぐに教えてくれます。
->
- object-operator - これは、インスタンスにアクセスするときに常に使用されます。
$bob = new Person;
echo $bob->name;
Person->foo
呼び出しは意味がないことに注意することが重要です (Person
はインスタンスではなくクラスであるため)。したがって、これは解析エラーです。
::
- scope-resolution-operator - クラスの静的プロパティまたはメソッドにアクセスするために常に使用されます。
echo Foo::bar()
さらに、同じ方法でオブジェクトの静的メソッドを呼び出すことができます。
echo $foo::bar()
外部からこれを行う場合、オブジェクトのインスタンスがメソッドから隠されることに注意することは非常に重要です。つまり、次の実行とまったく同じです。bar()
$class = get_class($foo);
$class::bar();
したがって、$this
静的呼び出しでは定義されません。
ここで少し事情が変わります。同じ演算子が使用されていますが、その意味はかなりあいまいになります。
object-operator は、->
オブジェクトのインスタンス状態を呼び出すために引き続き使用されます。
class Foo {
public $a = 1;
public function bar() {
return $this->a;
}
}
object-operator: を使用して(のインスタンス) でbar()
メソッドを呼び出すと、インスタンスのバージョンの が生成されます。$foo
Foo
$foo->bar()
$a
それが私たちが期待する方法です。
::
ただし、演算子の意味は変わります。現在の関数への呼び出しのコンテキストによって異なります。
静的コンテキスト内
静的コンテキスト内では、を使用して行われたすべての呼び出し::
も静的になります。例を見てみましょう:
class Foo {
public function bar() {
return Foo::baz();
}
public function baz() {
return isset($this);
}
}
呼び出すFoo::bar()
とbaz()
メソッドが静的に呼び出されるため、データは取り込まれ$this
ません。PHP の最近のバージョン (5.3 以降)E_STRICT
では、非静的メソッドを静的に呼び出しているため、エラーが発生することに注意してください。
インスタンスコンテキスト内
一方、インスタンス コンテキスト内では、 を使用して行われ::
た呼び出しは、呼び出しの受信者 (呼び出しているメソッド) に依存します。メソッドが として定義されているstatic
場合、静的呼び出しが使用されます。そうでない場合は、インスタンス情報を転送します。
したがって、上記のコードを見ると、呼び出し$foo->bar()
は を返しtrue
ます。これは、「静的」呼び出しがインスタンス コンテキスト内で発生するためです。
わかる?そうは思いませんでした。ややこしい。
クラス名を使用してすべてを結び付けるのはかなり汚いので、PHP はスコープ解決を容易にする 3 つの基本的な「ショートカット」キーワードを提供します。
self
- これは、現在のクラス名を参照します。クラス内self::baz()
と同じです(その上の任意のメソッド)。Foo::baz()
Foo
parent
- これは、現在のクラスの親を参照します。
static
- これは呼び出されたクラスを指します。継承のおかげで、子クラスはメソッドと静的プロパティをオーバーライドできます。したがってstatic
、クラス名の代わりに使用してそれらを呼び出すと、現在のレベルではなく、呼び出しがどこから来たかを解決できます。
これを理解する最も簡単な方法は、いくつかの例を見始めることです。クラスを選びましょう:
class Person {
public static $number = 0;
public $id = 0;
public function __construct() {
self::$number++;
$this->id = self::$number;
}
public $name = "";
public function getName() {
return $this->name;
}
public function getId() {
return $this->id;
}
}
class Child extends Person {
public $age = 0;
public function __construct($age) {
$this->age = $age;
parent::__construct();
}
public function getName() {
return 'child: ' . parent::getName();
}
}
さて、ここでは継承についても検討しています。これが悪いオブジェクト モデルであることはしばらく無視しますが、これをいじるとどうなるか見てみましょう。
$bob = new Person;
$bob->name = "Bob";
$adam = new Person;
$adam->name = "Adam";
$billy = new Child;
$billy->name = "Billy";
var_dump($bob->getId()); // 1
var_dump($adam->getId()); // 2
var_dump($billy->getId()); // 3
そのため、ID カウンターはインスタンスと子の両方で共有されます (これは、 を使用self
してアクセスしているためです。 を使用した場合はstatic
、子クラスでオーバーライドできます)。
var_dump($bob->getName()); // Bob
var_dump($adam->getName()); // Adam
var_dump($billy->getName()); // child: Billy
毎回Person::getName()
インスタンスメソッドを実行していることに注意してください。しかしparent::getName()
、ケースの 1 つ (子ケース) でそれを行うために を使用しています。これが、このアプローチを強力なものにしている理由です。
インスタンスが使用されるかどうかは、呼び出しコンテキストによって決まることに注意してください。したがって:
class Foo {
public function isFoo() {
return $this instanceof Foo;
}
}
常に正しいとは限りません。
class Bar {
public function doSomething() {
return Foo::isFoo();
}
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)
今、ここは本当に奇妙です。別のクラスを呼び出していますが$this
、メソッドに渡されるFoo::isFoo()
は のインスタンスです$bar
。
これにより、あらゆる種類のバグや概念的な WTF-ery が発生する可能性があります。::
したがって、これら 3 つの仮想 "ショートカット" キーワード ( static
、self
、および) を除いて、インスタンス メソッド内から演算子を避けることを強くお勧めしますparent
。
静的メソッドとプロパティは全員で共有されることに注意してください。それは基本的にそれらをグローバル変数にします。グローバルに伴うすべての同じ問題があります。そのため、真にグローバルであることを理解していない限り、静的メソッド/プロパティに情報を格納することを本当に躊躇します。
static
一般に、 の代わりに使用して、Late-Static-Binding と呼ばれるものを使用することをお勧めしますself
。ただし、それらは同じものではないことに注意してください。したがって、「static
代わりに常に使用する」と言うのself
は本当に近視眼的です。代わりに、立ち止まって、実行したい呼び出しについて考え、子クラスが静的に解決されたものをオーバーライドできるようにするかどうかを考えてください。電話。
残念ですが、読み返してみてください。長すぎるかもしれませんが、これは複雑なトピックなのでそれだけ長くなります
いいよ。つまり、はクラス内の現在のクラス名self
を参照するために使用され、 asは現在のオブジェクトインスタンスを参照します。コピー/貼り付けのショートカットであることに注意してください。クラス名に安全に置き換えることができ、問題なく動作します。ただし、事前に決定できない動的変数です (また、クラスではない場合もあります)。$this
self
$this
オブジェクト演算子が使用されている場合 ( ->
)、インスタンスを扱っていることが常にわかります。スコープ解決演算子が使用されている場合 ( ::
)、コンテキストに関する詳細情報が必要です (既にオブジェクト コンテキスト内にあるか? オブジェクトの外にいるか? など)。
self
($self ではない) はクラスのタイプ$this
を参照しますが、クラスの現在のインスタンスを参照します。 self
静的メンバー関数で使用して、静的メンバー変数にアクセスできるようにします。$this
非静的メンバー関数で使用され、メンバー関数が呼び出されたクラスのインスタンスへの参照です。
this
はオブジェクトなので、次のように使用します。$this->member
はオブジェクトではないためself
、基本的には現在のクラスを自動的に参照する型です。次のように使用します。self::member
$this->
クラスの変数 (メンバー変数) またはメソッドの特定のインスタンスを参照するために使用されます。
Example:
$derek = new Person();
$derek は Person の特定のインスタンスになりました。すべての Person には first_name と last_name がありますが、$derek には特定の first_name と last_name (Derek Martin) があります。$derek インスタンス内では、これらを $this->first_name および $this->last_name として参照できます。
ClassName:: は、そのタイプのクラスとその静的変数、静的メソッドを参照するために使用されます。それが役立つ場合は、「静的」という言葉を「共有」に置き換えることができます。これらは共有されているため、(共有されていない) 特定のインスタンスを参照する $this を参照することはできません。静的変数 (つまり static $db_connection) は、オブジェクト タイプのすべてのインスタンス間で共有できます。たとえば、すべてのデータベース オブジェクトは 1 つの接続 (静的 $connection) を共有します。
静的変数の例: 1 つのメンバ変数を持つデータベース クラスがあるとします。 static $num_connections; 次に、これをコンストラクターに入れます。
function __construct()
{
if(!isset $num_connections || $num_connections==null)
{
$num_connections=0;
}
else
{
$num_connections++;
}
}
オブジェクトにはコンストラクターがあるのと同様に、オブジェクトが死ぬか設定解除されたときに実行されるデストラクタもあります。
function __destruct()
{
$num_connections--;
}
新しいインスタンスを作成するたびに、接続カウンターが 1 つ増えます。インスタンスを破棄または使用を停止するたびに、接続カウンターが 1 つ減少します。このようにして、使用しているデータベース オブジェクトのインスタンスの数を監視できます。
echo DB::num_connections;
$num_connections は静的 (共有) であるため、アクティブなデータベース オブジェクトの総数が反映されます。この手法を使用して、データベース クラスのすべてのインスタンス間でデータベース接続を共有しているのを見たことがあるかもしれません。これは、データベース接続の作成に時間がかかるため、1 つだけ作成して共有することをお勧めします (これはシングルトン パターンと呼ばれます)。
静的メソッド (つまり public static View::format_phone_number($digits)) は、それらのオブジェクトの 1 つを最初にインスタンス化せずに使用できます (つまり、内部で $this を参照しません)。
静的メソッドの例:
public static function prettyName($first_name, $last_name)
{
echo ucfirst($first_name).' '.ucfirst($last_name);
}
echo Person::prettyName($derek->first_name, $derek->last_name);
ご覧のとおり、 public static 関数 prettyName はオブジェクトについて何も知りません。オブジェクトの一部ではない通常の関数のように、渡すパラメーターを操作するだけです。では、オブジェクトの一部としてそれを持たないことができるのであれば、なぜ気にする必要がありますか?
SELF::参照したい静的メソッドを持つオブジェクトの外側で コーディングしている場合は、オブジェクトの名前 View::format_phone_number($phone_number); を使用して呼び出す必要があります。参照したい静的メソッドを持つオブジェクト内でコーディングしている場合は、オブジェクトの名前 View::format_phone_number($pn) を使用するか、self::format_phone_number($pn) ショートカットを使用できます。
同じことが静的変数にも当てはまります: 例: View::templates_path と self::templates_path の比較
DB クラス内で、他のオブジェクトの静的メソッドを参照する場合は、オブジェクトの名前を使用します。 例: Session::getUsersOnline();
しかし、DB クラスがそれ自身の静的変数を参照したい場合は、単に self と言うだけです: 例: self::connection;
物事を解決するのに役立つことを願っています:)
PHP では、self キーワードを使用して静的プロパティとメソッドにアクセスします。
問題は、が static と宣言されているかどうかに関係なく$this->method()
、self::method()
どこでも置き換えることができることです。method()
では、どちらを使用する必要がありますか?
次のコードを検討してください。
class ParentClass {
function test() {
self::who(); // will output 'parent'
$this->who(); // will output 'child'
}
function who() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function who() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
この例では、self::who()
は常に「親」を出力$this->who()
しますが、オブジェクトのクラスによって異なります。
これで、 self はそれが呼び出されたクラスを$this
参照し、一方、現在のオブジェクトのクラスを参照していることがわかります。
$this
そのため、 が利用できない場合、または子孫クラスが現在のメソッドを上書きすることを許可したくない場合にのみ、 self を使用する必要があります。
クラス定義内で$this
は、現在のオブジェクトをself
参照し、 は現在のクラスを参照します。
クラス要素self
は で参照し、オブジェクト要素は で参照する必要があります$this
。
self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable
非静的および静的メンバー変数に対する$thisおよびselfの正しい使用例を次に示します。
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
静的キーワードによると、はありません$self
。$this
クラスの現在のインスタンス(オブジェクト)を参照するためのself
、、およびクラスの静的メンバーを参照するために使用できる、のみがあります。ここでは、オブジェクトインスタンスとクラスの違いが関係しています。
$this
は、現在のオブジェクトを参照します。static
は現在のオブジェクトを参照します。self
は、それが定義された正確なクラスを参照します。parent
は、それが定義された正確なクラスの親を参照します。オーバーロードを示す次の例を参照してください。
<?php
class A {
public static function newStaticClass()
{
return new static;
}
public static function newSelfClass()
{
return new self;
}
public function newThisClass()
{
return new $this;
}
}
class B extends A
{
public function newParentClass()
{
return new parent;
}
}
$b = new B;
var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A
class C extends B
{
public static function newSelfClass()
{
return new self;
}
}
$c = new C;
var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"
ほとんどの場合、現在のクラスを参照する必要があるため、static
またはを使用します$this
。ただし、拡張内容に関係なく、元のクラスが必要な場合があります。 self
(非常に、非常にめったに)
self
現在のクラス (呼び出されたクラス) を参照し、
$this
現在のオブジェクトを参照します。self の代わりに static を使用できます。
例を参照してください。
class ParentClass {
function test() {
self::which(); // Outputs 'parent'
$this->which(); // Outputs 'child'
}
function which() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function which() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
出力:
parent
child
を呼び出すことでクラスの静的メンバーを呼び出すことができるかどうかが問題ではなかったと思いますClassName::staticMember
。self::classmember
問題は、との使用の違いは何かということでした$this->classmember
。
たとえば、次の例はどちらも、使用するかどうかにかかわらず、エラーなしで機能しますself::
。$this->
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
$this->name = $new_name;
$this->address = $new_address;
}
}
class Person{
private $name;
private $address;
public function __construct($new_name,$new_address){
self::$name = $new_name;
self::$address = $new_address;
}
}
これは小さなベンチマークです( repl.it の7.2.24):
Speed (in seconds) Percentage
$this-> 0.91760206222534 100
self:: 1.0047659873962 109.49909865716
static:: 0.98066782951355 106.87288857386
4,000,000 回の実行の結果。結論:関係ありません。そして、ここに私が使用したコードがあります:
<?php
class Foo
{
public function calling_this() { $this->called(); }
public function calling_self() { self::called(); }
public function calling_static() { static::called(); }
public static function called() {}
}
$foo = new Foo();
$n = 4000000;
$times = [];
// warmup
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_this(); }
$times["this"] = microtime(true)-$start;
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_self(); }
$times["self"] = microtime(true)-$start;
$start = microtime(true);
for ($i = 0; $i < $n; $i++) { $foo->calling_static(); }
$times["static"] = microtime(true)-$start;
$min = min($times);
echo $times["this"] . "\t" . ($times["this"] / $min)*100 . "\n";
echo $times["self"] . "\t" . ($times["self"] / $min)*100 . "\n";
echo $times["static"] . "\t" . ($times["static"] / $min)*100 . "\n";
self
を演算子とともに使用すると、::
現在のクラスが参照されます。これは、静的コンテキストと非静的コンテキストの両方で実行できます。$this
オブジェクト自体を指します。さらに、$this
静的メソッドを呼び出すために使用することは完全に合法です (ただし、フィールドを参照することはできません)。
私は同じ質問に出くわしましたが、簡単な答えは次のとおりです。
$this
クラスのインスタンスが必要ですself::
しません静的メソッドまたは静的属性を使用していて、クラスのオブジェクトをインスタンス化せずにそれらを呼び出したい場合は常に、オブジェクトを作成する必要があるself:
ため、それらを呼び出す必要があります。$this
$this
は現在のクラス オブジェクトをself
参照し、現在のクラス (オブジェクトではない) を参照します。クラスはオブジェクトの設計図です。つまり、クラスを定義しますが、オブジェクトを構築します。
つまり、 と を使用self for static
しthis for none-static members or methods
ます。
また、子/親のシナリオでself / parent
は、主に子と親のクラス メンバーとメソッドを識別するために使用されます。
ケース 1:self
クラス定数に use を使用できる
クラスクラスA { const FIXED_NUMBER = 4; 自分::POUNDS_TO_KILOGRAMS }
クラスの外で呼び出したい場合はclassA::POUNDS_TO_KILOGRAMS
、定数へのアクセスに使用します
ケース 2: 静的プロパティの場合
クラスクラスC { public function __construct() { 自己::$_counter++; $this->num = self::$_counter; } }
php.net によると、このコンテキストself
には 、 、parent
およびの 3 つの特別なキーワードがありstatic
ます。これらは、クラス定義内からプロパティまたはメソッドにアクセスするために使用されます。
$this
一方、 は、そのクラスがアクセス可能である限り、任意のクラスのインスタンスとメソッドを呼び出すために使用されます。