Is subclass of: примеры (PHP)

Проверка наследования через is_subclass_of в PHP
Раздел: Объектно-ориентированное программирование
is_subclass_of(object|string $object_or_class, string $class, bool $allow_string = true): bool

Функция is_subclass_of определяет, принадлежит ли объект к подклассу указанного класса или реализует интерфейс. Используется для проверки иерархии наследования и соответствия типов в runtime.

Аргументы функции
  • object_or_class - проверяемый объект или имя класса в виде строки.
  • class - имя родительского класса или интерфейса для проверки.
  • allow_string (с PHP 7.3.0) - если false, первый параметр принимает только объекты.
Базовые примеры
Проверка наследования
class ParentClass {}
class ChildClass extends ParentClass {}

$obj = new ChildClass();
var_dump(is_subclass_of($obj, 'ParentClass'));
var_dump(is_subclass_of($obj, 'SomeClass'));
bool(true)
bool(false)
Использование строки с именем класса
var_dump(is_subclass_of('ChildClass', 'ParentClass'));
var_dump(is_subclass_of('ParentClass', 'ParentClass'));
bool(true)
bool(false)
Параметр allow_string
var_dump(is_subclass_of('ChildClass', 'ParentClass', false));
var_dump(is_subclass_of($obj, 'ParentClass', false));
bool(false)
bool(true)
Аналоги в PHP
instanceof

Оператор проверяет, является ли объект экземпляром класса или его потомком. Не работает с именами классов в строках.

$obj = new ChildClass();
var_dump($obj instanceof ParentClass);
bool(true)

Проверяет, принадлежит ли объект к классу или является его подклассом. Поддерживает строковые аргументы и параметр allow_string.

var_dump(is_a($obj, 'ParentClass'));
var_dump(is_a('ChildClass', 'ParentClass', true));
bool(true)
bool(true)
Аналоги в других языках
Python: issubclass()

Работает только с классами, а не с объектами.

class ParentClass:
    pass
class ChildClass(ParentClass):
    pass

print(issubclass(ChildClass, ParentClass))
# issubclass(obj, ParentClass) - TypeError
True
JavaScript: instanceof

Проверяет объекты, но не принимает имена классов как строки.

class ParentClass {}
class ChildClass extends ParentClass {}
const obj = new ChildClass();
console.log(obj instanceof ParentClass);
true
Типичные ошибки
Проверка несуществующего класса
var_dump(is_subclass_of('ChildClass', 'UnexistingClass'));
PHP Warning:  is_subclass_of(): Class UnexistingClass does not exist
Некорректный первый аргумент
var_dump(is_subclass_of(42, 'SomeClass'));
bool(false)
Сравнение с самим собой
$obj = new ParentClass();
var_dump(is_subclass_of($obj, 'ParentClass'));
bool(false)
Изменения в версиях PHP
PHP 7.3.0

Добавлен параметр allow_string. При установке в false функция не принимает имя класса в качестве первого аргумента.

PHP 5.3.7

Функция начала корректно обрабатывать интерфейсы. Ранее проверка is subclass of с интерфейсами могла возвращать неверные результаты.

Расширенные примеры
Проверка интерфейсов
Пример php
interface MyInterface {}
class Implementer implements MyInterface {}

$obj = new Implementer();
var_dump(is_subclass_of($obj, 'MyInterface'));
var_dump(is_subclass_of('Implementer', 'MyInterface'));
bool(true)
bool(true)
Динамическая проверка в абстрактной фабрике
Пример php
abstract class Document {}
class PdfDocument extends Document {}
class WordDocument extends Document {}

function createViewer(string $docClass) {
    if (!is_subclass_of($docClass, 'Document')) {
        throw new Exception('Неверный тип документа');
    }
    return new $docClass();
}

try {
    $viewer = createViewer('PdfDocument');
    echo get_class($viewer);
} catch (Exception $e) {
    echo $e->getMessage();
}
PdfDocument
Проверка в цепочке наследования
Пример php
class A {}
class B extends A {}
class C extends B {}

$obj = new C();
var_dump(is_subclass_of($obj, 'A'));
var_dump(is_subclass_of($obj, 'B'));
var_dump(is_subclass_of('C', 'A'));
bool(true)
bool(true)
bool(true)
Автозагрузка классов
Пример php
spl_autoload_register(function($class) {
    if ($class === 'DynamicClass') {
        eval('class DynamicClass extends ParentClass {}');
    }
});

var_dump(is_subclass_of('DynamicClass', 'ParentClass'));
bool(true)

PHP is_subclass_of function comments

En
Is subclass of Checks if the object has this class as one of its parents or implements it