はじめに
PHPの継承において「self::
と static::
の違い」は、試験でも実務でも頻出の落とし穴です。本記事では、遅延静的束縛(Late Static Bindings, LSB) の仕組みを具体例とともに解説し、誤答しやすいポイントを整理します。
目次
遅延静的束縛とは
PHPの「遅延静的束縛(Late Static Bindings, LSB)」は、継承クラスから呼び出した場合に、呼び出し元クラスを正しく参照できる仕組みです。
self::
→ コードが定義されているクラスに束縛される(静的解決)static::
→ 呼び出し元のクラスに束縛される(遅延解決)
サンプルコード
<?php
declare(strict_types=1);
error_reporting(-1);
class Hoge {
public static function func(){
echo __METHOD__ , "\n";
}
public static function callSelf(){
echo __METHOD__ , ", ";
self::func();
}
public static function callStatic(){
echo __METHOD__ , ", ";
static::func();
}
}
class Foo extends Hoge {
public static function func(){
echo __METHOD__ , "\n";
}
}
Foo::callSelf();
Foo::callStatic();
実行結果
Hoge::callSelf, Hoge::func
Hoge::callStatic, Foo::func
解説
Foo::callSelf();
- 実際に呼び出しているのは
Foo
だが、callSelf()
の定義はHoge
にある。 self::func()
は「定義されているクラス」で解決されるため、Hoge::func
が呼ばれる。- 👉 出力:
Hoge::callSelf, Hoge::func
Foo::callStatic();
callStatic()
の定義もHoge
にある。- しかし、
static::func()
は「呼び出し元のクラス」で解決されるため、Foo::func
が呼ばれる。 - 👉 出力:
Hoge::callStatic, Foo::func
試験の誤答パターンとの比較
呼び出し | 正しい出力 | 誤答しやすい出力例 |
---|---|---|
Foo::callSelf(); | Hoge::callSelf, Hoge::func | Foo::callSelf, Foo::func と誤解する |
Foo::callStatic(); | Hoge::callStatic, Foo::func | Hoge::callStatic, Hoge::func と誤解する |
特に static::
を self::
と同じだと勘違いすると誤答に繋がります。
まとめ
self::
→ 定義元クラスに固定static::
→ 呼び出し元クラスを解決(LSBが働く)- 試験問題では「
Foo::callStatic()
の出力は?」という形で出題されやすい
👉 実務でも「拡張クラス側のメソッドを呼びたいのに self::
を使ってしまった」トラブルが起きがちなので注意しましょう。