【PHP8.x】is_subclass_of関数の使い方

作成日: 更新日:

is_subclass_of関数は、指定されたクラスまたはオブジェクトが、特定の親クラスを継承しているか、あるいは特定のインターフェースを実装しているかを判断する関数です。この関数は、PHPのオブジェクト指向プログラミングにおいて、クラス間の継承関係や型の一致性を実行時に確認する際に非常に有用です。

第一引数には、判定の対象となるクラス名(文字列)またはそのクラスのインスタンス(オブジェクト)を指定します。第二引数には、比較対象となる親クラスまたはインターフェースの名前(文字列)を指定してください。

もし第一引数で指定されたクラスが第二引数のクラスを継承しているか、またはインターフェースを実装している場合、この関数はtrueを返します。それ以外の場合はfalseが返されます。

クラス名やインターフェース名の大文字・小文字は区別されず、PHPの内部で自動的に解決されます。これにより、コードの柔軟性を保ちながら、厳密な型チェックを行うことができます。特に、メソッドの引数として渡されたオブジェクトが期待する振る舞いを持つかを確認したり、多態性(ポリモーフィズム)を利用する際に、オブジェクトの型に基づいて異なる処理を行うための条件分岐などに活用されます。システムを構築する上で、オブジェクトの振る舞いを動的に検証し、適切なロジックを適用するために重要な役割を果たします。

基本的な使い方

構文(syntax)

<?php

class BaseClass {}
class SubClass extends BaseClass {}

$object = new SubClass();

is_subclass_of($object, 'BaseClass');

?>

引数(parameters)

object|string $object_or_class, string $class, bool $allow_string = true

  • object|string $object_or_class: クラス名またはオブジェクト
  • string $class: 比較対象のクラス名
  • bool $allow_string = true: trueの場合、クラス名文字列を渡せる

戻り値(return)

bool

指定されたクラスが、他のクラスのサブクラスである場合に true を返します。そうでない場合は false を返します。

サンプルコード

PHP: is_subclass_ofとinstanceofの違いを比較する

<?php

/**
 * PHPのis_subclass_of関数とinstanceof演算子の違いを比較するサンプルコード。
 *
 * is_subclass_of: あるクラスが別のクラスのサブクラスであるかをチェックします。
 *                 第一引数にオブジェクトまたはクラス名文字列、第二引数に親クラス名文字列を取ります。
 *                 インターフェースの実装チェックには使用できません。
 *
 * instanceof: あるオブジェクトが特定のクラスのインスタンスであるか、またはそのクラスを継承しているか、
 *             あるいは特定のインターフェースを実装しているかをチェックします。
 *             第一引数にオブジェクト、第二引数にクラス名またはインターフェース名を取ります。
 *             クラス名文字列を直接比較することはできません。
 */

// 継承関係を持つクラスを定義します
class Vehicle {}
class Car extends Vehicle {}

// インターフェースを定義し、それを実装するクラスを定義します
interface Drivable {}
class SportsCar extends Car implements Drivable {}

// 各クラスのオブジェクトを生成します
$vehicle = new Vehicle();
$car = new Car();
$sportsCar = new SportsCar();

echo "--- オブジェクトとクラス名の比較 ---\n";

// Case 1: オブジェクトが特定のクラスを継承しているかを確認
// $sportsCar は Car のサブクラスです。
echo "is_subclass_of(\$sportsCar, 'Car'): " . (is_subclass_of($sportsCar, 'Car') ? 'true' : 'false') . "\n";
echo "\$sportsCar instanceof Car: " . ($sportsCar instanceof Car ? 'true' : 'false') . "\n";

// $sportsCar は Vehicle のサブクラスです (多段継承)。
echo "is_subclass_of(\$sportsCar, 'Vehicle'): " . (is_subclass_of($sportsCar, 'Vehicle') ? 'true' : 'false') . "\n";
echo "\$sportsCar instanceof Vehicle: " . ($sportsCar instanceof Vehicle ? 'true' : 'false') . "\n";

// $car は SportsCar のサブクラスではありません。
echo "is_subclass_of(\$car, 'SportsCar'): " . (is_subclass_of($car, 'SportsCar') ? 'true' : 'false') . "\n";
echo "\$car instanceof SportsCar: " . ($car instanceof SportsCar ? 'true' : 'false') . "\n";


echo "\n--- クラス名文字列と親クラス名文字列の比較 (is_subclass_ofの利点) ---\n";

// Case 2: is_subclass_of はクラス名文字列同士での比較が可能です
// 'SportsCar' クラスは 'Car' クラスのサブクラスか?
echo "is_subclass_of('SportsCar', 'Car'): " . (is_subclass_of('SportsCar', 'Car') ? 'true' : 'false') . "\n";
// 'Car' クラスは 'Vehicle' クラスのサブクラスか?
echo "is_subclass_of('Car', 'Vehicle'): " . (is_subclass_of('Car', 'Vehicle') ? 'true' : 'false') . "\n";

// instanceof はクラス名文字列単体では使用できません。
// 例: 'SportsCar' instanceof 'Car' は構文エラーとなります。


echo "\n--- インターフェースの実装チェック ---\n";

// Case 3: インターフェースの実装チェックにおける違い
// $sportsCar は Drivable インターフェースを実装しています。

// is_subclass_of はクラスの継承関係のみをチェックし、インターフェースの実装はチェックしません。
// インターフェースはクラスのサブクラスではないため、false を返します。
echo "is_subclass_of(\$sportsCar, 'Drivable'): " . (is_subclass_of($sportsCar, 'Drivable') ? 'true' : 'false') . "\n";

// instanceof はクラスの継承関係に加えて、インターフェースの実装もチェックします。
echo "\$sportsCar instanceof Drivable: " . ($sportsCar instanceof Drivable ? 'true' : 'false') . "\n";

// $car は Drivable インターフェースを実装していません。
echo "is_subclass_of(\$car, 'Drivable'): " . (is_subclass_of($car, 'Drivable') ? 'true' : 'false') . "\n";
echo "\$car instanceof Drivable: " . ($car instanceof Drivable ? 'true' : 'false') . "\n";

?>

PHPには、クラスの継承関係やオブジェクトの型をチェックする際に、is_subclass_of関数とinstanceof演算子の2つの方法があります。

is_subclass_of関数は、第一引数にオブジェクトまたはクラス名文字列、第二引数に親クラス名文字列を取り、あるクラスが別のクラスのサブクラスであるかを真偽値(bool)で返します。この関数は、オブジェクトだけでなくクラス名文字列同士の継承関係を直接確認できる点が特徴です。ただし、インターフェースの実装チェックには対応していません。

一方、instanceof演算子は、左辺にオブジェクト、右辺にクラス名またはインターフェース名を指定し、そのオブジェクトが指定されたクラスのインスタンスであるか、またはそのクラスを継承しているか、あるいは指定されたインターフェースを実装しているかを真偽値で判定します。instanceofはクラス名文字列を直接比較することはできません。

したがって、クラス名文字列の継承関係を動的に調べたい場合はis_subclass_ofを、オブジェクトが特定のインターフェースを実装しているかや、特定のクラスのインスタンスであるか(継承を含む)を調べたい場合はinstanceofを使用すると良いでしょう。

is_subclass_ofは、主にクラス間の継承関係のみを調べ、第一引数にオブジェクトまたはクラス名文字列を指定できる点が特徴です。一方、instanceofはオブジェクトが特定のクラスのインスタンスか、その継承クラスか、あるいはインターフェースを実装しているかを調べます。最も重要な注意点は、is_subclass_ofがインターフェースの実装をチェックしないことです。インターフェースの実装を確認する場合は必ずinstanceofを使用してください。クラス名文字列で動的に継承関係を調べたい場合はis_subclass_ofが役立ちますが、オブジェクトの型チェック全般にはinstanceofがより一般的で推奨されます。

【PHP8.x】is_subclass_of関数の使い方 | いっしー@Webエンジニア