はじめに
PHPのオブジェクト指向で頻出する「クラスの関係判定」。
特に、instanceof 演算子と is_subclass_of() 関数の違いを混同しやすいポイントです。
「どちらもクラスを判定する」ように見えて、実は判定範囲に明確な違いがあります。
この記事では、PHP8上級試験の例題コードをもとに、出力結果の理由を図解付きで丁寧に解説します。
目次
🧠コード例
<?php
declare(strict_types=1);
error_reporting(-1);
class Hoge {}
class Foo extends Hoge {}
$fn = function($obj, $class){
var_dump($obj instanceof $class);
var_dump(is_subclass_of($obj, $class));
};
$obj = new Foo();
$fn($obj, Foo::class);
$fn($obj, Hoge::class);■ 想定される出力(誤答)
問題集などで「全て true」としているケースがありますが、
これは 誤り です。
bool(true)
bool(true)
bool(true)
bool(true)正しくは次のとおりです 👇
bool(true)
bool(false)
bool(true)
bool(true)■ 理由を分解して理解する
まず、継承関係を整理します。
class Hoge {}
class Foo extends Hoge {}- Foo は Hoge を「継承」している(= サブクラス)
- Hoge は Foo の「親クラス(スーパークラス)」
■ instanceof の動作
instanceof は 「同じクラス、またはその子孫クラス」 を判定します。
| 式 | 意味 | 結果 |
|---|---|---|
$obj instanceof Foo | Foo のインスタンス? | ✅ |
$obj instanceof Hoge | Hoge のインスタンス(またはその子)? | ✅ |
■ is_subclass_of() の動作
一方、is_subclass_of() は 「サブクラスかどうか」 に限定して判定します。
つまり「同じクラス」は false になります。
| 式 | 意味 | 結果 |
|---|---|---|
is_subclass_of($obj, Foo::class) | Foo のサブクラス? | ❌(同じクラスなので違う) |
is_subclass_of($obj, Hoge::class) | Hoge のサブクラス? | ✅ |
🧩 図解:継承関係と判定範囲
Hoge
↑
│ ← Foo は Hoge を継承
│
Foo
↑
│
$obj = new Foo()
instanceof Hoge → ✅(親も含む)
instanceof Foo → ✅(自分も含む)
is_subclass_of Hoge → ✅(Foo は Hoge のサブクラス)
is_subclass_of Foo → ❌(Foo は Foo のサブクラスではない)🧭 まとめ
| 判定式 | 判定対象 | 結果 |
|---|---|---|
$obj instanceof Foo | 同一 or サブクラス | ✅ |
$obj instanceof Hoge | 親クラスも含む | ✅ |
is_subclass_of($obj, Foo::class) | サブクラスのみ | ❌ |
is_subclass_of($obj, Hoge::class) | サブクラス(Foo→Hoge) | ✅ |
