静的メンバーはクラス変数の一種であり、クラスのインスタンスではなくクラス全体に属すると考えることができます。一般的なインスタンス変数とは異なり、静的メンバーは 1 つの変数値のみを保持し、この変数値はすべてのインスタンスに対して有効です。つまり、すべてのインスタンスがこのメンバーを共有します。
$this はクラスの現在のインスタンスのみを表し、self:: はクラス自体を表します。この演算子はクラス外のコードでは使用できず、継承ツリー階層内の位置を識別できません。つまり、拡張クラスで self スコープを使用する場合、self は基本クラスで宣言されたメソッドを呼び出すことができますが、常に拡張クラスでオーバーライドされたメソッドを呼び出します。 $this とは異なり、静的変数を使用する場合は、スコープ修飾子の後に $ 記号を追加する必要があります。
拡張クラスでは、基本クラスのメソッドがオーバーライドされると、親スコープを使用して基本クラスで定義されたメソッドを呼び出します。静的メンバーは親クラスにのみ所属することもできます。メンバーがサブクラスと親クラスの両方で宣言されている場合は、parant:: を使用して、サブクラス内の親クラスの変数にアクセスすることもできます。この場合、親クラスの静的メンバーとサブクラスの静的メンバーは異なる値を保持します。
:: 演算子の左側にクラスの名前を記述して、クラスのインスタンスの作成を避けるためにメンバーに静的にアクセスできます。クラスをインスタンス化する必要がなくなるだけでなく、クラスの各インスタンスが占めるシステム リソースの一部が小さくなるため、より効率的になります。
:: 演算子を使用してメンバー変数にアクセスする場合は、$ 記号の使用に再度注意する必要があります。 PHP は現在、動的静的変数の使用をサポートしていないため、つまり、変更可能な静的変数をサポートしていません。 $this->$var を使用する場合、アクセスされるメンバーは $var に含まれる変数の値です。 $ 記号を使用して変数にアクセスする代わりに、実際にはクラスの定数を探していますが、$this を介して定数にアクセスすることはできません。
PHP6 で提案されている static::scope により、self:: とparent:: を使用する必要がなくなります。関数を実装する最終クラスを指定する場合は、 static:: を使用できます。この修飾子は、コードが実行される直前に、継承階層の最後のクラスのメンバーを計算します。 1 つのプロセスは遅延バインディングと呼ばれ、これを使用すると、子クラスの静的変数をオーバーライドしたり、親クラスで宣言された関数から最後のメンバーにアクセスしたりすることができます。
場合によっては、すべてのクラス インスタンスで共有され、すべてのクラス インスタンスに関連するが、特定のオブジェクトからは呼び出すことができないフィールドとメソッドを作成することが必要になる場合があります。たとえば、Web ページへの訪問者数を追跡するクラスを作成するとします。クラスをインスタンス化するたびに訪問者数を 0 にリセットする必要はありません。この時点で、フィールドを静的スコープに設定できます。
リーリープログラムの実行結果:
1
2
$visitors フィールドは静的に宣言されているため、その値への変更はインスタンス化されたすべてのオブジェクトに反映されます。また、静的フィールドとメソッドは、this とアロー演算子ではなく、self キーワードとクラス名を使用して参照する必要があることに注意してください。これは、「通常の」メソッドを使用して静的フィールドを参照することは不可能であり、構文エラーが発生するためです。
クラス内で $this を使用して静的フィールドを参照することはできません。
静的変数
クラスでは、static キーワードには主に 2 つの用途があります。1 つは静的メンバーの定義、もう 1 つは静的メソッドの定義です。クラス内では、スコープ修飾子 (::) を使用して、さまざまなレベルのスコープの変数にアクセスできます。
静的メソッド
静的メソッドと非静的メソッドを使用するための原則: まず、メソッドに $this 変数が含まれていない場合は、静的メソッドにする必要があります。クラスのインスタンスが必要ない場合は、静的クラスを使用することもできます。これにより、クラスの作業をインスタンス化する必要がなくなります。さらに、静的メソッドは特定のインスタンスに属さないため、$this 変数を静的メソッドで使用することはできません。