PHP 5では、self
と$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();
?>
以下は、メンバー関数に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から :
投稿者 http://board.phpbuilder.com/member.php?145249-laserlight
キーワードselfは、少なくとも現在のクラスを参照するだけで、静的メンバーに限定するという意味ではありませんNOT。非静的メンバーのコンテキスト内では、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();
これは出力されます:
こんにちは、こんにちは。
Ludwigの人からさよなら
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()
を呼び出すと、 "Person is alice"と表示されますが、スコープにはself::getStatus()
の呼び出しが定義されたときの元のメソッド定義が含まれているため、 "Person is alive"と表示されます。
PHP 5.3には解決策があります。 static::
解決演算子は "Late static binding"を実装しています。 status()
の行をstatic::getStatus()
に変更すると、期待どおりの結果が得られます。 PHPの古いバージョンでは、これを行うためのクラッジを見つける必要があります。
そう質問されていない質問に答えるために...
$this->
は現在のオブジェクト(クラスのインスタンス)を表し、static::
はクラスを表します
self
対$this
について話しているときに何を話しているのかを本当に理解するには、実際に概念的および実用的なレベルで何が起こっているかを掘り下げる必要があります。私は本当に答えがこれを適切に行うとは思わないので、ここに私の試みがあります。
classおよびobjectが何であるかについて話を始めましょう。
それで、 is aclass?多くの人は、オブジェクトに対してblueprintまたはtemplateとして定義しています。実際、もっと読むことができます PHPここのクラスについて 。そして、ある程度までそれは実際にそうです。クラスを見てみましょう:
class Person {
public $name = 'my name';
public function sayHello() {
echo "Hello";
}
}
おわかりのように、そのクラスには$name
という名前のプロパティとsayHello()
という名前のメソッド(関数)があります。
veryは、classが静的構造であることに注意することが重要です。つまり、クラスPerson
は、一度定義されると、どこで見ても常に同じです。
一方、オブジェクトは、クラスのinstanceと呼ばれるものです。つまり、クラスの「設計図」を取得し、それを使用して動的コピーを作成します。このコピーは、保存されている変数に明確に関連付けられています。したがって、instanceへの変更は、そのインスタンスに対してローカルです。
$bob = new Person;
$adam = new Person;
$bob->name = 'Bob';
echo $adam->name; // "my name"
new
演算子を使用して、クラスの新しいinstancesを作成します。
したがって、クラスはグローバル構造であり、オブジェクトはローカル構造であると言います。面白い->
構文について心配する必要はありません。少し詳しく説明します。
話すべきもう1つのことは、インスタンスがinstanceof
特定のクラスである場合、checkできることです。ブール値を返す$bob instanceof Person
$bob
インスタンスがPerson
クラスを使用して作成された場合、orPerson
の子。
それでは、クラスに実際に含まれているものを少し掘り下げてみましょう。クラスに含まれる「もの」には5つのタイプがあります。
Properties-これらは、各インスタンスに含まれる変数と考えてください。
class Foo {
public $bar = 1;
}
Static Properties-これらをクラスレベルで共有される変数と考えてください。つまり、各インスタンスによってコピーされることはありません。
class Foo {
public static $bar = 1;
}
Methods-これらは、各インスタンスに含まれる(およびインスタンスで動作する)関数です。
class Foo {
public function bar() {}
}
Staticメソッド-これらはクラス全体で共有される関数です。それらはインスタンスに対して not 操作を行いますが、代わりに静的プロパティのみに対して操作します。
class Foo {
public static function bar() {}
}
Constants-クラスは定数を解決しました。ここでは詳しく説明しませんが、完全を期すために追加します。
class Foo {
const BAR = 1;
}
基本的に、情報が共有されている(したがって静的である)かどうかを識別するstaticについての「ヒント」を使用して、クラスおよびオブジェクトコンテナーに情報を格納していますしたがって動的)。
メソッドの内部では、オブジェクトのインスタンスは$this
変数で表されます。そのオブジェクトの現在の状態があり、プロパティを変更(変更)すると、そのインスタンスが変更されます(他のインスタンスは変更されません)。
メソッドが静的に呼び出される場合、$this
変数は定義されません。これは、静的呼び出しに関連付けられたインスタンスがないためです。
ここで興味深いのは、静的呼び出しがどのように行われるかです。状態にアクセスする方法について説明しましょう。
その状態を保存したので、それにアクセスする必要があります。これには少し注意が必要です(または way 少し以上)、インスタンス/クラスの外部から(たとえば、通常の関数呼び出しから、または(グローバルスコープから)、およびインスタンス/クラス内(オブジェクトのメソッド内から)。
インスタンス/クラスの外側から見ると、ルールは非常にシンプルで予測可能です。 2つの演算子があり、それぞれがインスタンスまたはクラスstaticを処理しているかどうかをすぐに通知します。
->
-object-operator-これは、インスタンスにアクセスするときに常に使用されます。
$bob = new Person;
echo $bob->name;
Person->foo
の呼び出しは意味をなさないことに注意することが重要です(Person
はインスタンスではなくクラスであるため)。したがって、それは解析エラーです。
::
-scope-resolution-operator-これは、クラスの静的プロパティまたはメソッドにアクセスするために常に使用されます。
echo Foo::bar()
さらに、同じ方法でオブジェクトの静的メソッドを呼び出すことができます。
echo $foo::bar()
extremelyは、これを outside から行うと、オブジェクトのインスタンスがbar()
から隠されることに注意することが重要です。方法。実行とまったく同じという意味です:
$class = get_class($foo);
$class::bar();
したがって、$this
は静的呼び出しで定義されていません。
ここで状況は少し変わります。同じ演算子が使用されますが、それらの意味はかなりあいまいになります。
object-operator->
は、オブジェクトのインスタンス状態の呼び出しに引き続き使用されます。
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
は not に設定されます。最近のバージョンのPHP(5.3+)では、静的ではないメソッドを呼び出しているため、E_STRICT
エラーが発生することに注意してください。
インスタンスコンテキスト内
一方、インスタンスコンテキスト内では、::
を使用して行われる呼び出しは、呼び出しの受信者(呼び出しているメソッド)に依存します。メソッドがstatic
として定義されている場合、静的呼び出しを使用します。そうでない場合は、インスタンス情報を転送します。
したがって、上記のコードを見て、$foo->bar()
を呼び出すと、true
が返されます。これは、「静的」呼び出しがインスタンスコンテキスト内で発生するためです。
理にかなっていますか?そうは思わなかった。ややこしい。
クラス名を使用してすべてを結び付けるのはかなり面倒なので、PHPはスコープを簡単に解決するための3つの基本的な「ショートカット」キーワードを提供します。
self
-これは現在のクラス名を指します。 self::baz()
は、Foo
クラス(その上の任意のメソッド)内のFoo::baz()
と同じです。
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()
instanceメソッドを実行していることに注意してください。ただし、いずれかのケース(子ケース)でparent::getName()
を使用しています。これがこのアプローチを強力にするものです。
呼び出しコンテキストは、インスタンスが使用されるかどうかを決定するものであることに注意してください。したがって:
class Foo {
public function isFoo() {
return $this instanceof Foo;
}
}
always trueではありません。
class Bar {
public function doSomething() {
return Foo::isFoo();
}
}
$b = new Bar;
var_dump($b->doSomething()); // bool(false)
ここでreallyが変わっています。別のクラスを呼び出していますが、Foo::isFoo()
メソッドに渡される$this
は$bar
のインスタンスです。
これは、あらゆる種類のバグと概念的なWTF-eryを引き起こす可能性があります。したがって、3つの仮想「ショートカット」キーワード(static
、self
、およびparent
)を除くすべてのインスタンスメソッドで、::
演算子を使用しないことを強くお勧めします。 。
静的メソッドとプロパティは全員で共有されることに注意してください。それは基本的にそれらをグローバル変数にします。グローバルに伴うすべての同じ問題で。したがって、情報が本当にグローバルであることに慣れていない限り、静的なメソッド/プロパティに情報を格納することをためらいます。
一般に、static
の代わりにself
を使用して、遅延静的バインディングと呼ばれるものを使用する必要があります。しかし、それらは同じものではないので、「static
の代わりに常にself
を使用する」というのは本当に近視眼的であることに注意してください。static resolve呼び出しをオーバーライドできる子クラス。
残念ですが、戻って読んでください。長すぎるかもしれませんが、これは複雑なトピックなので長すぎます
いいよ。つまり、self
はクラス内の現在のクラス名を参照するために使用されます。ここで、$this
は現在のオブジェクトを参照しますinstance。 self
はコピー/貼り付けのショートカットであることに注意してください。クラス名で安全に置き換えることができ、正常に機能します。しかし、$this
は動的変数であり、事前に決定することはできません(クラスでさえない場合があります)。
オブジェクト演算子(->
)が使用されている場合、alwaysインスタンスを処理していることがわかります。 scope-resolution-operatorが使用されている場合(::
)、コンテキストに関する詳細情報が必要です(すでにオブジェクトコンテキストにいますか?オブジェクトの外にいますか?など)。
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を参照することはできません。これは特定のインスタンスを参照します(共有されていません)。静的変数(つまり、静的$ db_connection)は、ある種類のオブジェクトのすべてのインスタンス間で共有できます。たとえば、すべてのデータベースオブジェクトは単一の接続(static $ 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);
ご覧のとおり、public static function prettyNameはオブジェクトについて何も知りません。オブジェクトの一部ではない通常の関数のように、渡されたパラメータを使用しているだけです。それでは、それをオブジェクトの一部としてではなくても構わないとしたら、なぜ迷惑なのでしょうか。
SELF ::コーディングしている場合outside必要な静的メソッドを持つオブジェクトを参照してください、あなたはオブジェクトの名前を使用してそれを呼び出す必要がありますView :: format_phone_number($ phone_number);inside参照したい静的メソッドを持つオブジェクトをコーディングしている場合は、bothuseオブジェクトの名前View :: format_phone_number($ pn)、OR self :: format_phone_number($ pn)のショートカットを使用できます。
同じことが静的変数にも言えます:例:View :: templates_pathとself :: templates_path
DBクラスの内部で、他のオブジェクトの静的メソッドを参照している場合は、オブジェクトの名前を使用します。例:Session :: getUsersOnline( ;
しかし、DBクラスがそれ自身の静的変数を参照したい場合、それは単にselfを言うでしょう:例:self :: connection;
それが物事をクリアするのに役立ちます願っています:)
このブログ投稿から:
self
は現在のクラスを参照しますself
は、静的関数を呼び出して静的メンバー変数を参照するために使用できます。self
は静的関数内で使用できますself
はvtableを迂回することで多態性の振る舞いを止めることもできます$this
は現在のオブジェクトを参照します$this
は静的関数を呼び出すために使用できます$this
を静的メンバ変数の呼び出しに使用しないでください。代わりにself
を使用してください。$this
は静的関数内では使用できません
PHPでは、selfキーワードを使用して静的プロパティと静的メソッドにアクセスします。
問題は、$this->method()
がstaticとして宣言されているかどうかにかかわらず、self::method()
をmethod()
anywhereに置き換えることができるということです。それで、あなたはどれを使うべきですか?
このコードを見てください:
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()
は常に「parent」を出力しますが、$this->who()
はオブジェクトのクラスによって異なります。
$this
は現在のオブジェクトのクラスを参照していますが、selfはそれが呼び出されているクラスを参照しています。
そのため、$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();
?>
によると http://www.php.net/manual/en/language.oop5.static.php$self
はありません。現在のクラスのインスタンス(オブジェクト)を参照するための$this
と、クラスの静的メンバーを参照するために使用できるselfだけがあります。ここでは、オブジェクトインスタンスとクラスの違いが出てきます。
self
は現在のクラスを参照します
$this
は現在のオブジェクトを参照します。あなたはselfの代わりにstaticを使うことができます。例を見てください。
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();
出力:親子
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;
}
}
ここでだれも公演について話していなかったので、ここに私がした小さなベンチマークがあります(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();
過負荷を示す次の例を参照してください。
<?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
を使用します。ただし、needself
のように拡張しても元のクラスが必要なため、必要な場合があります。 (非常に、非常にまれ)
self
が::
演算子と一緒に使用されるとき、それは現在のクラスを参照します。これは、静的コンテキストでも非静的コンテキストでも行うことができます。 $this
はオブジェクトそのものを参照します。さらに、静的メソッドを呼び出すために$this
を使用することは完全に合法です(ただし、フィールドを参照することはできません)。
$this
は現在のクラスオブジェクトを表し、self
は現在のクラスを表します(オブジェクトではありません)。クラスはオブジェクトの青写真です。だからあなたはクラスを定義するが、あなたはオブジェクトを構築する。
つまり、self for static
とthis for none-static members or methods
を使用してください。
また、子/親シナリオでは、self / parent
は主に子クラスと親クラスのメンバーとメソッドを識別するために使用されます。
さらに、$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;
の使用法も表します。
私は同じ質問に出くわした、そして簡単な答えは:
静的メソッドまたは静的属性を使用していて、クラスのオブジェクトをインスタンス化せずにそれらを呼び出したい場合は、必ず使用する必要がありますself ::を呼び出すには、$ thisを作成するには常にオブジェクトが必要です。
そのクラスのオブジェクト/インスタンスを作成せずにそのクラスのメソッドを呼び出したい場合はself
を使用してください。したがって、 RAM を節約できますその目的)。つまり、実際にはメソッドを静的に呼び出しています。オブジェクトの観点からthis
を使用してください。
ケース1:使用self
はクラス定数に使用できます
class classA { const FIXED_NUMBER = 4; self :: POUNDS_TO_KILOGRAMS }
クラス外で呼び出したい場合は、classA::POUNDS_TO_KILOGRAMS
を使用して定数にアクセスします。
ケース2:静的プロパティ
クラスclassC { パブリック関数__construct(){ self :: $ _ counter ++; $ this-> num = self :: $ _ counter; } }
Php.netによると、この文脈には3つの特別なキーワードがあります:self
、parent
およびstatic
。それらはクラス定義の中からプロパティやメソッドにアクセスするために使われます。
一方、$this
は、そのクラスがアクセス可能である限り、任意のクラスのインスタンスとメソッドを呼び出すために使用されます。