2152

selfPHP 5では、とを使用することの違いは何$thisですか?

それぞれが適切なのはいつですか?

4

23 に答える 23

1871

短い答え

$this現在のオブジェクトを参照するために使用します。self現在のクラスを参照するために使用します。つまり、 $this->member非静的メンバーに使用self::$memberし、静的メンバーに使用します。

フルアンサー

非静的および静的メンバー変数のおよびの正しい使用例を次に示します。$thisself

<?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();
?>

非静的および静的メンバー変数のおよびの誤った使用例を次に示します。$thisself

<?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から:

http://board.phpbuilder.com/member.php?145249-laserlight _

于 2008-09-30T06:29:25.627 に答える
760

キーワード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、呼び出された関数内のポインターにアクセスできます。

于 2009-07-27T18:00:42.863 に答える
483

使用しないでください 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::参照します。

于 2011-07-24T15:08:22.287 に答える
263

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$bobPersonPerson

状態の定義

それでは、クラスに実際に含まれているものを少し掘り下げてみましょう。クラスに含まれる「もの」には、次の 5 種類があります。

  1. プロパティ- これらは、各インスタンスに含まれる変数と考えてください。

    class Foo {
        public $bar = 1;
    }
    
  2. 静的プロパティ- これらは、クラス レベルで共有される変数と考えてください。つまり、各インスタンスによってコピーされることはありません。

    class Foo {
        public static $bar = 1;
    }
    
  3. メソッド- これらは、各インスタンスに含まれる (およびインスタンスで動作する) 関数です。

    class Foo {
        public function bar() {}
    }
    
  4. 静的メソッド- クラス全体で共有される関数です。これらはインスタンスでは機能せ、代わりに静的プロパティのみで機能します。

    class Foo {
        public static function bar() {}
    }
    
  5. 定数- クラス解決定数。ここではこれ以上深く掘り下げませんが、完全を期すために追加します。

    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()メソッドを呼び出すと、インスタンスのバージョンの が生成されます。$fooFoo$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 つ (子ケース) でそれを行うために を使用しています。これが、このアプローチを強力なものにしている理由です。

注意事項 #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 つの仮想 "ショートカット" キーワード ( staticself、および) を除いて、インスタンス メソッド内から演算子を避けることを強くお勧めしますparent

注意事項 #2

静的メソッドとプロパティは全員で共有されることに注意してください。それは基本的にそれらをグローバル変数にします。グローバルに伴うすべての同じ問題があります。そのため、真にグローバルであることを理解していない限り、静的メソッド/プロパティに情報を格納することを本当に躊躇します。

注意事項 #3

static一般に、 の代わりに使用して、Late-Static-Binding と呼ばれるものを使用することをお勧めしますself。ただし、それらは同じものではないことに注意してください。したがって、「static代わりに常に使用する」と言うのselfは本当に近視眼的です。代わりに、立ち止まって、実行したい呼び出しについて考え、子クラスが静的に解決されたものをオーバーライドできるようにするかどうかを考えてください。電話。

TL/DR

残念ですが、読み返してみてください。長すぎるかもしれませんが、これは複雑なトピックなのでそれだけ長くなります

TL/DR #2

いいよ。つまり、はクラス内の現在のクラス名selfを参照するために使用され、 asは現在のオブジェクトインスタンスを参照します。コピー/貼り付けのショートカットであることに注意してください。クラス名に安全に置き換えることができ、問題なく動作します。ただし、事前に決定できない動的変数です (また、クラスではない場合もあります)。$thisself$this

TL/DR #3

オブジェクト演算子が使用されている場合 ( ->)、インスタンスを扱っていることが常にわかります。スコープ解決演算子が使用されている場合 ( ::)、コンテキストに関する詳細情報が必要です (既にオブジェクト コンテキスト内にあるか? オブジェクトの外にいるか? など)。

于 2013-06-10T15:21:28.410 に答える
122

self($self ではない) はクラスのタイプ$thisを参照しますが、クラスの現在のインスタンスを参照します。 self静的メンバー関数で使用して、静的メンバー変数にアクセスできるようにします。$this非静的メンバー関数で使用され、メンバー関数が呼び出されたクラスのインスタンスへの参照です。

thisはオブジェクトなので、次のように使用します。$this->member

はオブジェクトではないためself、基本的には現在のクラスを自動的に参照する型です。次のように使用します。self::member

于 2008-09-30T07:26:16.410 に答える
99

$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 はオブジェクトについて何も知りません。オブジェクトの一部ではない通常の関数のように、渡すパラメーターを操作するだけです。では、オブジェクトの一部としてそれを持たないことができるのであれば、なぜ気にする必要がありますか?

  1. まず、オブジェクトに関数を追加すると、物事を整理しておくのに役立ち、どこにあるかがわかります。
  2. 第二に、名前の競合を防ぎます。大規模なプロジェクトでは、2 人の開発者が getName() 関数を作成する可能性があります。一方が ClassName1::getName() を作成し、もう一方が ClassName2::getName() を作成しても、まったく問題ありません。競合はありません。イェーイ静的メソッド!

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;

物事を解決するのに役立つことを願っています:)

于 2008-10-22T17:52:00.153 に答える
27

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 を使用する必要があります。

于 2014-12-29T13:20:20.600 に答える
22

クラス定義内で$thisは、現在のオブジェクトをself参照し、 は現在のクラスを参照します。

クラス要素selfは で参照し、オブジェクト要素は で参照する必要があります$this

self::STAT // refer to a constant value
self::$stat // static variable
$this->stat // refer to an object variable  
于 2013-05-08T06:58:59.743 に答える
21

非静的および静的メンバー変数に対する$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();
?> 
于 2011-12-06T11:26:22.880 に答える
20

静的キーワードによると、はありません$self$thisクラスの現在のインスタンス(オブジェクト)を参照するためのself、、およびクラスの静的メンバーを参照するために使用できる、のみがあります。ここでは、オブジェクトインスタンスとクラスの違いが関係しています。

于 2008-09-30T06:29:17.843 に答える
20
  • のオブジェクトポインタ$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(非常に、非常にめったに)

于 2013-03-22T15:24:23.317 に答える
20

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
于 2016-01-01T06:36:43.480 に答える
17

を呼び出すことでクラスの静的メンバーを呼び出すことができるかどうかが問題ではなかったと思いますClassName::staticMemberself::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;
    }
}
于 2009-05-18T19:42:36.210 に答える
14

これは小さなベンチマークです( 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";
于 2015-05-31T07:09:31.523 に答える
13

selfを演算子とともに使用すると、::現在のクラスが参照されます。これは、静的コンテキストと非静的コンテキストの両方で実行できます。$thisオブジェクト自体を指します。さらに、$this静的メソッドを呼び出すために使用することは完全に合法です (ただし、フィールドを参照することはできません)。

于 2013-03-22T15:13:36.330 に答える
11

私は同じ質問に出くわしましたが、簡単な答えは次のとおりです。

  • $thisクラスのインスタンスが必要です
  • self::しません

静的メソッドまたは静的属性を使用していて、クラスのオブジェクトをインスタンス化せずにそれらを呼び出したい場合は常に、オブジェクトを作成する必要があるself:ため、それらを呼び出す必要があります。$this

于 2018-05-19T15:23:49.373 に答える
7

$thisは現在のクラス オブジェクトをself参照し、現在のクラス (オブジェクトではない) を参照します。クラスはオブジェクトの設計図です。つまり、クラスを定義しますが、オブジェクトを構築します。

つまり、 と を使用self for staticthis for none-static members or methodsます。

また、子/親のシナリオでself / parentは、主に子と親のクラス メンバーとメソッドを識別するために使用されます。

于 2014-09-15T06:36:28.857 に答える
2

ケース 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;
   }
}
于 2016-02-02T20:51:51.027 に答える
1

php.net によると、このコンテキストselfには 、 、parentおよびの 3 つの特別なキーワードがありstaticます。これらは、クラス定義内からプロパティまたはメソッドにアクセスするために使用されます。

$this一方、 は、そのクラスがアクセス可能である限り、任意のクラスのインスタンスとメソッドを呼び出すために使用されます。

于 2015-12-07T10:21:24.357 に答える