11

次のコードを検討してください。

abstract class ExampleClass
{
    public static function regularStaticFunction()
    {
        return static::abstractStaticFunction();
    }

    abstract protected static function abstractStaticFunction();
}

ExampleClass::regularStaticFunction();

PhpStorm IDE は、次のような宣言に警告を表示しabstractStaticFunctionます。

PHP の厳格な基準: 静的関数 'abstractStaticFunction' は抽象化できません。

静的関数は抽象的であってはなりません。

ただし、PHP はこのクラスを解析するときにプログラムの実行を続行し、次のように出力します。

PHP の厳格な標準: 静的関数 ExampleClass::abstractStaticFunction() は、7 行目の php シェル コードで抽象化されるべきではありません

PHP では抽象クラスでの静的関数呼び出しが許可されているため、抽象クラスで抽象静的関数を定義することはできないようです。

なぜ無意味な抽象静的関数がインタプリタによって PHP で許可されているのですか?

4

2 に答える 2

32

これは、 Mark Ameryによるこの回答からの適切な説明です。

PHP バグ レポート 53081static::foo()では、構造体の追加により抽象静的メソッドが合理的かつ有用になったため、警告を削除するよう求められました 。Rasmus Lerdorf (PHP の作成者) は、要求が偽物であるとラベル付けすることから始め、警告を正当化しようとする長い一連の悪い推論をたどります。そして最後に、次の交換が行われます。

ジョルジオ

知ってるけど:

abstract class cA
{
      //static function A(){self::B();} error, undefined method
      static function A(){static::B();} // good
      abstract static function B();
}

class cB extends cA
{
    static function B(){echo "ok";}
}

cB::A();

ラスムス

そうです、それはまさにそれがどのように機能するべきかです。

ジョルジオ

しかし、それは許可されていません:(

ラスムス

何が許可されていませんか?

abstract class cA {
      static function A(){static::B();}
      abstract static function B();
}

class cB extends cA {
    static function B(){echo "ok";}
}

cB::A();

これはうまくいきます。明らかに self::B() を呼び出すことはできませんが、 static::B() は問題ありません。

彼の例のコードが「正常に動作する」という Rasmus の主張は誤りです。ご存じのとおり、厳格モードの警告がスローされます。彼は厳密モードをオンにせずにテストしていたと思います。とにかく、混乱した Rasmus は、リクエストを「偽物」として誤って閉じたままにしました。

そして、それが警告がまだ言語にある理由です。これは完全に満足のいく説明ではないかもしれません - あなたはおそらく警告の合理的な正当化を期待してここに来ました. 残念ながら、現実の世界では、合理的な意思決定ではなく、ありふれた過ちや不適切な推論から選択が生まれることがあります。これは単にそれらの時間の 1 つです。

幸いなことに、評価の高い Nikita Popov が、 PHP RFC: Reclassify E_STRICT noticesの一部として、PHP 7 の言語から警告を削除しました。最終的には正気を保てるようになり、PHP 7 がリリースされれabstract staticば、このばかげた警告を受けることなく、誰もが問題なく使用できるようになります。

于 2017-01-12T11:18:49.177 に答える