はじめに
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:: を使ってしまった」トラブルが起きがちなので注意しましょう。
