Is a: примеры (PHP)

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

Функция is_a() проверяет, является ли переданный объект экземпляром указанного класса или родительского класса по отношению к нему. Также она может проверить, реализует ли объект определенный интерфейс. Функция используется в объектно-ориентированном программировании для проверки типа объекта во время выполнения программы (runtime type checking).

Синтаксис: is_a(mixed $object_or_string, string $class, bool $allow_string = false): bool

Аргументы:

  • object_or_string (mixed) – Проверяемый объект или, если третий параметр $allow_string установлен в true, имя класса в виде строки.
  • class (string) – Имя ожидаемого класса или интерфейса.
  • allow_string (bool) – Если этот параметр равен false, то строковое значение в первом аргументе вызовет ошибку. Начиная с PHP 8.0, значение по умолчанию – false. При значении true функция примет строку с именем класса как корректный аргумент для проверки.

Функция возвращает true, если объект $object_or_string является экземпляром класса $class или его потомком, либо реализует указанный интерфейс. В противном случае возвращает false.

Простые примеры использования is_a
Базовый пример с объектом
<?php
class ParentClass {}
class ChildClass extends ParentClass {}

$obj = new ChildClass();

var_dump(is_a($obj, 'ChildClass'));
var_dump(is_a($obj, 'ParentClass'));
var_dump(is_a($obj, 'SomeOtherClass'));
bool(true)
bool(true)
bool(false)
Пример с интерфейсом
<?php
interface MyInterface {}
class MyClass implements MyInterface {}

$obj = new MyClass();

var_dump(is_a($obj, 'MyInterface'));
bool(true)
Пример с параметром allow_string (PHP 8.0+)
<?php
class MyClass {}
$obj = new MyClass();
$className = 'MyClass';

// С allow_string = true
var_dump(is_a($obj, $className, true));
// Передача строки вместо объекта
var_dump(is_a($className, $className, true));

// С allow_string = false (по умолчанию) - вызовет ошибку в PHP 8.0+, если передать строку
// var_dump(is_a($className, $className)); // Ошибка TypeError
bool(true)
bool(true)
Похожие функции в PHP
  • instanceof (оператор) – Выполняет ту же проверку, что и is_a(), но является оператором, а не функцией. Часто считается более предпочтительным из-за лучшей производительности и читаемости. Например: $obj instanceof MyClass. Не поддерживает параметр $allow_string для проверки имени класса в виде строки без объекта.
  • get_class() – Возвращает имя класса объекта. Сравнение можно выполнить вручную: get_class($obj) === 'MyClass'. Однако такая проверка не учитывает наследование, в отличие от is_a() или instanceof.
  • is_subclass_of() – Проверяет, является ли объект подклассом указанного класса. Ключевое отличие от is_a() в том, что is_subclass_of() возвращает false, если объект является экземпляром самого проверяемого класса, а не его потомком.

Рекомендации: Для большинства случаев проверки типа объекта лучше использовать оператор instanceof. Функция is_a() полезна, когда имя класса динамически формируется и хранится в строковой переменной, особенно с параметром $allow_string. Также is_a() может быть удобна в контексте функций обратного вызова (callback).

Аналоги функции в других языках
Python: isinstance()
class ParentClass:
    pass
class ChildClass(ParentClass):
    pass

obj = ChildClass()
print(isinstance(obj, ChildClass))   # True
print(isinstance(obj, ParentClass))  # True
print(isinstance(obj, str))          # False
# Также поддерживает проверку кортежа классов
print(isinstance(obj, (ParentClass, str))) # True (проверяет на соответствие любому типу из кортежа)
True
True
False
True
JavaScript: instanceof
class ParentClass {}
class ChildClass extends ParentClass {}

const obj = new ChildClass();
console.log(obj instanceof ChildClass);   // true
console.log(obj instanceof ParentClass);  // true
console.log(obj instanceof String);       // false
true
true
false

Is a в MySQL

В MySQL нет прямой аналогии для проверки типа объекта во время выполнения, так как это язык запросов к реляционным базам данных, а не объектно-ориентированный язык программирования. Однако можно использовать операторы проверки типов данных для столбцов, например, CAST() или JSON_TYPE() для работы с JSON.

Распространенные ошибки
Передача строки с allow_string = false (PHP 8.0+)
<?php
// Начиная с PHP 8.0, по умолчанию allow_string = false
$className = 'DateTime';
// Следующий вызов вызовет TypeError
var_dump(is_a($className, $className));
Fatal error: Uncaught TypeError: is_a(): Argument #1 ($object_or_string) must be of type object, string given...
Использование несуществующего имени класса
<?php
$obj = new stdClass();
// Если класс не существует, функция вернет false (при условии, что autoload не загрузит класс).
// Однако если передать строку с allow_string=true, проверка пройдет, но смысла в этом мало.
var_dump(is_a($obj, 'NonExistentClass', true));
// С объектом и несуществующим классом - false
var_dump(is_a($obj, 'NonExistentClass'));
bool(false)
bool(false)
Путаница между is_a и get_class
<?php
class A {}
class B extends A {}

$obj = new B();

// is_a проверяет иерархию наследования
var_dump(is_a($obj, 'A')); // true
// Простое сравнение имени класса - наследование не учитывается
var_dump(get_class($obj) === 'A'); // false
bool(true)
bool(false)
Изменения в версиях PHP
  • PHP 8.0: Значение параметра $allow_string по умолчанию изменено с true на false. Это критическое изменение (BC break), так как вызов is_a() со строкой в первом аргументе без явного указания третьего параметра теперь вызывает TypeError. Сама сигнатура функции стала строго типизированной.
  • PHP 8.1: Функция is_a() теперь может использоваться как функция обратного вызова, передаваемая в функции, ожидаующие callable.
  • PHP 8.3: Существенных изменений в поведении функции не было.
Расширенные примеры
Динамическая проверка с переменным именем класса
Пример php
<?php
interface LoggerInterface {
    public function log($message);
}

class FileLogger implements LoggerInterface {
    public function log($message) { /* ... */ }
}

class DatabaseLogger implements LoggerInterface {
    public function log($message) { /* ... */ }
}

function processLogger($logger) {
    // Динамическая проверка через переменную
    $expectedInterface = 'LoggerInterface';
    if (is_a($logger, $expectedInterface)) {
        echo 'Логгер корректен.';
        $logger->log('Сообщение');
    } else {
        echo 'Передан неверный тип логгера.';
    }
}

processLogger(new FileLogger());
processLogger(new stdClass());
Логгер корректен.
Передан неверный тип логгера.
Использование в массиве с array_filter
Пример php
<?php
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
class Car {}

$objects = [
    new Dog(),
    new Cat(),
    new Car(),
    new Dog(),
    null
];

// Отфильтруем только объекты, являющиеся Animal
$animals = array_filter($objects, fn($obj) => is_a($obj, 'Animal'));
print_r($animals);
Array
(
    [0] => Dog Object
        ( )
    [1] => Cat Object
        ( )
    [3] => Dog Object
        ( )
)
Проверка на несколько типов (эмуляция)
Пример php
<?php
class Foo {}
class Bar {}
class Baz {}

$obj = new Bar();

// В PHP нет встроенной проверки на несколько типов, но можно использовать:
$allowedClasses = ['Foo', 'Bar', 'SomeOtherClass'];
$isAllowed = false;
foreach ($allowedClasses as $class) {
    if (is_a($obj, $class)) {
        $isAllowed = true;
        break;
    }
}
var_dump($isAllowed);

// Или с использованием call_user_func и is_a (PHP 8.1+ как callable)
$check = function ($object, $classes) {
    foreach ($classes as $class) {
        if (is_a($object, $class)) return true;
    }
    return false;
};
var_dump($check($obj, $allowedClasses));
bool(true)
bool(true)
Работа с встроенными классами и stdClass
Пример php
<?php
$date = new DateTime();
$array = [1, 2, 3];
$stdObj = (object)['key' => 'value'];

var_dump(is_a($date, 'DateTime'));      // true
var_dump(is_a($date, 'DateTimeImmutable')); // false
var_dump(is_a($array, 'ArrayObject'));  // false, массив - не объект
var_dump(is_a($stdObj, 'stdClass'));    // true
// stdClass не имеет родительских классов
var_dump(is_a($stdObj, 'Iterator'));    // false
bool(true)
bool(false)
bool(false)
bool(true)
bool(false)

PHP is_a function comments

En
Is a Checks if the object is of a given type or subtype