以下のコードを実行してバックトレース出力を見ると、静的コンテキストで呼び出されたときに PHP が instanceFunc() を静的メソッドに変換することがわかります。ただし、インスタンス コンテキストでは、インスタンス呼び出しとして扱います。
ミックスにインスタンス変数を導入する (コメントアウトされた行を削除する) と、静的呼び出しから instanceFunc() を呼び出したときに致命的なエラーが発生します。
これは、PHP が本質的に静的である (インスタンス変数が処理されない) すべてのメソッドを静的コンテキストから呼び出すことを許可することを意味します。このコントラクトが破られるとすぐに、エラーが生成されます。したがって、静的関数の使用は、他のオブジェクト指向言語と調和するための唯一の良い習慣のようです。
staticFunc() に関しては、両方の呼び出しは、PHP がこれらを静的呼び出しとして解釈することを示しています。これは予想されることです。
class A {
private $x = 5;
private $y = 6;
private $z;
public function instanceFunc() {
//$this->z = $this->y * $this->x;
//echo $this->z;
var_dump(reset(debug_backtrace()));
}
public static function staticFunc() {
var_dump(reset(debug_backtrace()));
}
}
$a = new A();
A::instanceFunc(); // static call of intended instance method
$a->instanceFunc(); // instance call of instance method
A::staticFunc();
$a->staticFunc();
出力例 (コメント付きで実行されるコード):
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(19) ["function"]=> string(12) "instanceFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } }
array(7) { ["file"]=> string(59) "test.php" ["line"]=> int(22) ["function"]=> string(12) "instanceFunc" ["class"]=> string(1) "A" ["object"]=> object(A)#8 (3) { ["x:private"]=> int(5) ["y:private"]=> int(6) ["z:private"]=> NULL } ["type"]=> string(2) "->" ["args"]=> array(0) { } }
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(24) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } }
array(6) { ["file"]=> string(59) "test.php" ["line"]=> int(26) ["function"]=> string(10) "staticFunc" ["class"]=> string(1) "A" ["type"]=> string(2) "::" ["args"]=> array(0) { } }