PHPポストスタティックバインディングの定義と使用例を詳しく解説

伊谢尔伦
リリース: 2023-03-14 09:58:02
オリジナル
1514 人が閲覧しました

マニュアルの原文: PHP 5.3.0 以降、PHP には遅延静的バインディングと呼ばれる機能が追加され、 は継承スコープ内で静的に呼び出されるクラスを参照するために使用されます。

後期静的バインディングの動作原理は、前の「非転送呼び出し」にクラス名を保存することです。静的メソッド呼び出しを行う場合、クラス名は明示的に指定されたもの (通常は :: 演算子の左側) であり、非静的メソッド呼び出しを行う場合は、オブジェクトが属するクラスです。いわゆる「転送呼び出し」とは、self::、parent::、static::、および forward_static_call() の方法で行われる静的呼び出しを指します。 get_called_class() 関数を使用すると、呼び出されたメソッドのクラス名を取得でき、static:: はそのスコープを示します。

この機能は、言語内部の観点から「遅延静的バインディング」と呼ばれています。 「遅延バインディング」とは、static:: が現在のメソッドが定義されているクラスに解決されず、実際の実行時に計算されることを意味します。静的メソッドの呼び出し (ただし、それに限定されない) に使用できるため、「静的バインディング」とも呼ばれます。

self:: の制限 現在のメソッドが定義されているクラスに応じて、現在のクラスへの静的参照には self:: または __CLASS__ を使用します。

例 #1 self:: 使用法

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who();
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
ログイン後にコピー

上記のルーチンは出力します:

A

遅延静的バインディングの使用法 遅延静的バインディングは、実行時に最初に呼び出されるクラスを表す新しいキーワードを導入することで制限を回避することを目的としていました。簡単に言うと、このキーワードを使用すると、上記の例で test() を呼び出すときに、クラス A の代わりにクラス B を参照できるようになります。最終的には、新しいキーワードを導入せず、すでに予約されている静的キーワードを使用することが決定されました。

例 #2 static:: 簡単な使用法

<?php
class A {
public static function who() {
echo __CLASS__;
}
public static function test() {
static::who(); // 后期静态绑定从这里开始
}
}
class B extends A {
public static function who() {
echo __CLASS__;
}
}
B::test();
?>
ログイン後にコピー

上記のルーチンは次の出力を行います:

B

注: 非静的環境では、呼び出されるクラスはオブジェクト インスタンスが属するクラスです。 $this-> は同じスコープ内の private メソッドを呼び出そうとするため、static:: は異なる結果を返す可能性があります。もう 1 つの違いは、static:: は静的プロパティでのみ使用できることです。

例 #3 static::

<?php
class A {
private function foo() {
echo "success!\n";
}
public function test() {
$this->foo();
static::foo();
}
}
class B extends A {
/* foo() will be copied to B, hence its scope will still be A and
* the call be successful */
}
class C extends A {
private function foo() {
/* original method is replaced; the scope of the new one is C */
}
}
$b = new B();
$b->test();
$c = new C();
$c->test(); //fails
?>
ログイン後にコピー

の使用 上記のルーチンは出力します:

success!

success!

success!

致命的なエラー: コンテキスト 'A' からのプライベート メソッド C::foo() の呼び出し/tmp/test.php の 9 行目

注: 後期静的バインディングの解析は、完全に解析された静的呼び出しが取得されるまで続行されます。一方、parent:: または self:: を使用して静的に呼び出された場合は、呼び出し情報が転送されます。

例 #4 呼び出しの転送と非転送

<?php
class A {
public static function foo() {
static::who();
}
public static function who() {
echo __CLASS__."\n";
}
}
class B extends A {
public static function test() {
A::foo();
parent::foo();
self::foo();
}
public static function who() {
echo __CLASS__."\n";
}
}
class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}
C::test();
?>
ログイン後にコピー

上記のルーチンは出力します:

A

C

C


次の例は、PHP の遅延に基づいて、継承スコープ内の静的呼び出しを参照するソリューションを分析します。静的バインディング関数のタイプ。

まず次のコードを見てください:

class Person
{
public static function status()
{
self::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is alive
ログイン後にコピー

明らかに、結果は私たちが期待したものではありません。これは、self:: が実行中のクラスではなく、定義されているクラスに依存しているためです。この問題を解決するには、継承されたクラスの status() メソッドをオーバーライドすることができます。より良い解決策は、PHP 5.3 に遅延静的バインディングの機能を追加することです。

コードは次のとおりです:

class Person
{
public static function status()
{
static::getStatus();
}
protected static function getStatus()
{
echo "Person is alive";
}
}
class Deceased extends Person
{
protected static function getStatus()
{
echo "Person is deceased";
}
}
Deceased::status(); //Person is deceased
ログイン後にコピー

static:: が現在のクラスを指していないことがわかります。実際、実行時に計算され、最終クラスのすべてのプロパティが強制的に取得されます。

したがって、self:: はもう使用せず、static::

を使用することをお勧めします。

以上がPHPポストスタティックバインディングの定義と使用例を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート