回答:
$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();
?>
次に、メンバー関数にを使用して多態性の動作を抑制する例を示し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
スコープ解決演算子と共に使用され::
ます。これは、静的と非静的の両方のコンテキストで実行できます。さらに、$this
静的メソッドの呼び出しに使用することは完全に合法です(フィールドを参照することはできません)。
$this::
ですか?
キーワード自己んしない、少なくともない静的メンバーにあなたを制限した方法で、「現在のクラス」に過ぎない参照してください。非静的メンバーのコンテキスト内で、現在のオブジェクトself
のvtable(vtableのwikiを参照)をバイパスする方法も提供します。を使用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
)の両方として理解できます。
$this::
ですか?
$this::
。考えられるすべてのケースは、より一般的に使用される構文ですでにカバーされています。あなたが何を意味するかに応じて、使用$this->
、self::
またはstatic::
。
DO NOTを使用self::
、使用static::
自己の別の側面があります::言及する価値があります。厄介な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()
では、「Person is故人」が表示されると予想されますが、呼び出し先self::getStatus()
が定義されたときにスコープには元のメソッド定義が含まれているため、表示されるのは「Person is alive」です。
PHP 5.3には解決策があります。static::
解決演算子の実装は、それが呼ばれるクラスのスコープにバインドされていますというのファンシーな方法である「遅延静的バインディング」。の行status()
を static::getStatus()
と、期待どおりの結果なります。PHPの古いバージョンでは、これを行うための手がかりを見つける必要があります。
したがって、尋ねられたとおりではない質問に答えるために...
$this->
現在のオブジェクト(クラスのインスタンス)をstatic::
参照し、クラスを参照
getStatus
メソッドを、クラスではなくクラスインスタンスに対して呼び出すものと考えています。
self::
必要な場合、それを得ることができます。紛らわしい、例えば、特定のクラス名を使用してMyClass::
。
self
対について話しているときに何が話しているのかを本当に理解するには$this
、概念レベルと実用レベルで何が起こっているのかを実際に掘り下げる必要があります。私はどの回答もこれを適切に実行しているとは本当に感じていません。
クラスとオブジェクトが何であるかについて話すことから始めましょう。
だから、何であるクラスは?多くの人はそれを青写真またはオブジェクトのテンプレートとして定義します。実際、PHPのクラスについてはこちらをご覧ください。そして、それが実際にはある程度です。クラスを見てみましょう:
class Person {
public $name = 'my name';
public function sayHello() {
echo "Hello";
}
}
ご存知のように、そのクラスに呼び出されるプロパティと$name
と呼ばれるメソッド(関数)がありsayHello()
ます。
それはだ非常ことに注意することが重要なクラスは静的な構造です。つまり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を処理しているかどうかは、それぞれすぐにわかります。
->
- オブジェクトオペレーター -これは、インスタンスにアクセスするときに常に使用されます。
$bob = new Person;
echo $bob->name;
呼び出しPerson->foo
は意味がないことに注意してください(Person
インスタンスではなくクラスであるため)。したがって、これは解析エラーです。
::
- スコープ解像度オペレータ -これは常にクラスの静的プロパティまたはメソッドにアクセスするために使用されます。
echo Foo::bar()
さらに、同じ方法でオブジェクトの静的メソッドを呼び出すことができます。
echo $foo::bar()
それはだ非常に我々はこれを行う際に注意することが重要外側から、オブジェクトのインスタンスがから隠されているbar()
方法。それは実行とまったく同じであることを意味します:
$class = get_class($foo);
$class::bar();
したがって、$this
静的呼び出しでは定義されていません。
ここで状況が少し変わります。同じ演算子が使用されますが、それらの意味は著しく不明瞭になります。
オブジェクト演算子は ->
、まだ、オブジェクトのインスタンス状態への呼び出しを行うために使用されています。
class Foo {
public $a = 1;
public function bar() {
return $this->a;
}
}
オブジェクトオペレーターを使用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
を参照するために使用され$this
ます。asは、現在のオブジェクトインスタンスを参照します。これself
はコピー/貼り付けのショートカットです。安全にクラス名に置き換えることができ、問題なく動作します。しかし$this
、事前に決定できない動的な変数です(そして、クラスでさえないかもしれません)。
オブジェクトオペレーターが使用されている場合(->
)、インスタンスを処理していることが常にわかります。scope-resolution-operatorが使用されている場合(::
)、コンテキストに関する詳細情報が必要です(既にオブジェクトコンテキストにありますか?オブジェクトの外部にいますか?など)。
$this
"Strict Standards"に従い、静的として定義されていないメソッドを静的に呼び出さない場合は定義されません。あなたがここで説明した結果が表示されます:3v4l.org/WeHVM同意、本当に変です。
Foo::isFoo()
静的に呼び出される$this
ため、定義されません。私の意見では、これはより直感的な行動です。- から拡張すると、別の異なる結果が表示さBar
れFoo
ます。その場合、呼び出しFoo::isFoo()
は実際にはインスタンスコンテキスト内になります(PHP7に固有ではありません)。
$this->
クラスの変数(メンバー変数)またはメソッドの特定のインスタンスを参照するために使用されます。
Example:
$derek = new Person();
$ derekはPersonの特定のインスタンスになりました。すべての人にはfirst_nameとlast_nameがありますが、$ derekには特定のfirst_nameとlast_nameがあります(Derek Martin)。$ derekインスタンス内では、$ this-> first_nameおよび$ this-> last_nameとして参照できます。
ClassName ::は、そのタイプのクラス、およびその静的変数、静的メソッドを参照するために使用されます。それが役立つ場合は、「静的」という単語を「共有」に精神的に置き換えることができます。共有されているため、特定のインスタンス(共有されていない)を参照する$ thisを参照することはできません。静的変数(つまり、静的$ db_connection)は、オブジェクトタイプのすべてのインスタンス間で共有できます。たとえば、すべてのデータベースオブジェクトは単一の接続(静的$ connection)を共有します。
静的変数の例: 単一のメンバー変数を持つデータベースクラスがあるとします: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);
ご覧のとおり、パブリック静的関数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;
それが物事を明確にするのに役立つことを願っています:)
$
記号を使用する必要があることです。例self::$templates_path
PHPでは、selfキーワードを使用して静的プロパティとメソッドにアクセスします。
問題は、が静的と宣言されているかどうかに関係なく$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()
、オブジェクトのクラスに応じて、常に「親」を出力します。
これで、自分自身が呼び出さ$this
れたクラスを参照している一方で、現在のオブジェクトのクラスを参照していることがわかります。
そのため、が使用$this
できない場合、または子孫クラスが現在のメソッドを上書きできないようにする場合にのみ、selfを使用する必要があります。
http://www.php.net/manual/en/language.oop5.static.phpによると、はありません$self
。$this
クラス(オブジェクト)の現在のインスタンスを参照するためのと、クラスの静的メンバーを参照するために使用できるself のみがあります。ここでは、オブジェクトインスタンスとクラスの違いが関係しています。
クラスの静的メンバーをで呼び出すことができるかどうかは問題ではなかったと思います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;
}
}
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
self
現在のクラス(それが呼び出されるクラス)を参照し、
$this
現在のオブジェクトを参照します。自分の代わりに静的を使用できます。例を参照してください。
class ParentClass {
function test() {
self::which(); // output 'parent'
$this->which(); // output 'child'
}
function which() {
echo 'parent';
}
}
class ChildClass extends ParentClass {
function which() {
echo 'child';
}
}
$obj = new ChildClass();
$obj->test();
出力:親子
$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
ため、必要になる場合があります。(とても、めったにない)
ここでは誰もパフォーマンスについて話さなかったので、ここに私がした小さなベンチマークがあります(5.6):
Name | Time | Percent
----------|---------|---------
$this-> | 0.99163 | 106.23%
self:: | 0.96912 | 103.82%
static:: | 0.93348 | 100%
これらは2 000 000回の実行の結果であり、これが私が使用したコードです。
<?php
require '../vendor/autoload.php';
// My small class to do benchmarks
// All it does is looping over every test x times and record the
// time it takes using `microtime(true)`
// Then, the percentage is calculated, with 100% being the quickest
// Times are being rouned for outputting only, not to calculate the percentages
$b = new Tleb\Benchmark\Benchmark(2000000);
class Foo
{
public function calling_this()
{
$this->called();
}
public function calling_self()
{
self::called();
}
public function calling_static()
{
static::called();
}
public static function called()
{
}
}
$b->add('$this->', function () { $foo = new Foo; $foo->calling_this(); });
$b->add('self::', function () { $foo = new Foo; $foo->calling_self(); });
$b->add('static::', function () { $foo = new Foo; $foo->calling_static(); });
$b->run();
1 / 2e9 s = 0.5 ns
ています
use
キーワードtbhを使用しなかった理由はわかりませんが、ベンチマークをやり直すためのPHPがなくなったため、再インストールする気がありません。
さらに、以来、$this::
まだ議論されていません。
情報提供のみを目的として、PHP 5.3以降では、インスタンス化されたオブジェクトを処理して現在のスコープ値を取得するときに、を使用するのstatic::
ではなく、を使用することもでき$this::
ます。
class Foo
{
const NAME = 'Foo';
//Always Foo::NAME (Foo) due to self
protected static $staticName = self::NAME;
public function __construct()
{
echo $this::NAME;
}
public function getStaticName()
{
echo $this::$staticName;
}
}
class Bar extends Foo
{
const NAME = 'FooBar';
/**
* override getStaticName to output Bar::NAME
*/
public function getStaticName()
{
$this::$staticName = $this::NAME;
parent::getStaticName();
}
}
$foo = new Foo; //outputs Foo
$bar = new Bar; //outputs FooBar
$foo->getStaticName(); //outputs Foo
$bar->getStaticName(); //outputs FooBar
$foo->getStaticName(); //outputs FooBar
上記のコードを使用することは一般的または推奨される方法ではありませんが、単にその使用法を説明するためのものであり、「ご存知ですか?」元の投稿者の質問を参照してください。
それはまたの使用表す$object::CONSTANT
ための例echo $foo::NAME;
とは対照的に$this::NAME;
ケース1:self
クラス定数に使用できる
クラスclassA { const FIXED_NUMBER = 4; self :: POUNDS_TO_KILOGRAMS }
クラスの外で呼び出したい場合は、を使用classA::POUNDS_TO_KILOGRAMS
して定数にアクセスします
ケース2:静的プロパティの場合
クラスclassC { パブリック関数__construct(){ self :: $ _ counter ++; $ this-> num = self :: $ _ counter; } }
self :: キーワードは現在のクラスに使用され、基本的には静的メンバー、メソッド、定数にアクセスするために使用されます。しかし、$ thisの場合、静的メンバー、メソッド、関数を呼び出すことはできません。
別のクラスでself ::キーワードを使用して、静的メンバー、メソッド、および定数にアクセスできます。親クラスから拡張される場合、$ thisキーワードの場合も同じです。親クラスから拡張される場合、別のクラスの非静的メンバー、メソッド、および関数にアクセスできます。
以下のコードは、self ::および$ thisキーワードの例です。コードをコピーしてコードファイルに貼り付け、出力を確認するだけです。
class cars{
var $doors=4;
static $car_wheel=4;
public function car_features(){
echo $this->doors." Doors <br>";
echo self::$car_wheel." Wheels <br>";
}
}
class spec extends cars{
function car_spec(){
print(self::$car_wheel." Doors <br>");
print($this->doors." Wheels <br>");
}
}
/********Parent class output*********/
$car = new cars;
print_r($car->car_features());
echo "------------------------<br>";
/********Extend class from another class output**********/
$car_spec_show=new spec;
print($car_spec_show->car_spec());