題の通りです。端的に言うと親クラスでstatic::
を使って子クラス配下の静的なメソッドなりクラス名なりを呼ぶ時の挙動が変わります。これの対策には常にparent::
を使うことです。概ね直感的な挙動をしてくれます。
挙動の違いの具体例は次です。
<?php class A { public static function echoClass(): void { echo static::class; } public function echoClassDynamic(): void { echo static::class; } } class B extends A{} class C extends B{} class D extends C{ public static function echoClass(): void { // 静的メソッドの中の呼出しでは // parent を使うと親の static:: まで自分のクラスが伝播する parent::echoClass();// D // 親クラスを直に指定すると static:: で参照されるのは指定したクラス C::echoClass();// C B::echoClass();// B } public function echoClassDynamic(): void { // 動的メソッドの中の呼出しでは // どの場合でも自分のクラスが伝播する parent::echoClassDynamic();// D C::echoClassDynamic();// D B::echoClassDynamic();// D } } D::echoClass(); (new D)->echoClassDynamic();
コメントにある通り、静的メソッドの中では呼び出し方でどのクラスがstatic::
で参照されるクラスか変わります。これとクラス名を利用した機能が合わさると期待したクラス名が参照されずに期待しない挙動に繋がり問題が起きるということがあります。
このクラスの参照の仕組みは遅延静的束縛として名づけられて次のページにあります。
PHP: 遅延静的束縛 (Late Static Bindings) – Manual
中身はややこしいですがこの仕組みを端に発する問題に遭わない方法は親クラスを指定する時はparent::
で指定する、というそれだけです。