Get declared classes: примеры (PHP)

Использование get_declared_classes для получения списка классов
Раздел: Объектно-ориентированное программирование
get_declared_classes: array

Описание функции get_declared_classes

Основное назначение

Функция get_declared_classes() возвращает одномерный массив с именами всех классов, определенных в текущем скрипте, включая классы, загруженные через автозагрузку или объявленные вручную. Эта функция не принимает параметров.

Когда используется

Функция применяется при отладке для проверки доступных классов, в системах плагинов для динамического поиска классов, в ORM для автоматического маппинга или в инструментах статического анализа кода.

Аргументы функции

У функции отсутствуют параметры. Начиная с PHP 8, сигнатура выглядит так: get_declared_classes(): array.

Короткие примеры использования

Базовый вызов

Получение списка всех доступных классов:

<?php
$classes = get_declared_classes();
print_r($classes);
?>
Array
(
    [0] => stdClass
    [1] => Exception
    [2] => Error
    ... // много встроенных классов PHP
)
Проверка наличия класса

Определение, объявлен ли определенный класс:

<?php
class MyClass {}
$allClasses = get_declared_classes();
$isDeclared = in_array('MyClass', $allClasses);
var_dump($isDeclared);
?>
bool(true)

Похожие функции в PHP

В PHP существуют несколько функций для получения метаинформации о структурах:

Возвращает массив всех объявленных интерфейсов. Используется, когда требуется работать именно с интерфейсами.

Возвращает массив всех объявленных трейтов (доступно с PHP 5.4). Полезно для анализа использования трейтов.

Проверяет, был ли объявлен класс. Более эффективна для проверки одного конкретного класса, чем поиск в массиве от get_declared_classes().

Возвращает имя класса объекта. Используется для работы с экземплярами, а не для получения списка классов.

Аналоги в других языках

Get declared classes в Python

В Python нет прямой аналогии, но можно использовать dir() или модуль inspect:

import inspect
import sys

# Получение всех классов в текущем модуле
classes = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass)]
print(classes)
['MyClass', 'AnotherClass']

Get declared classes в Javascript

В JavaScript нет встроенной функции для получения всех классов. Можно собирать классы из глобального объекта или использовать системы модулей.

// Пример для Node.js, сбор из globalThis
const classes = [];
for (const key of Object.getOwnPropertyNames(globalThis)) {
    const val = globalThis[key];
    if (typeof val === 'function' && val.toString().startsWith('class')) {
        classes.push(key);
    }
}
console.log(classes);
[] // зависит от окружения

Get declared classes в MySQL

В SQL подобная функциональность отсутствует, так как язык не является объектно-ориентированным.

Типичные ошибки использования

Ожидание актуального списка после автозагрузки

Функция возвращает классы, объявленные на момент вызова. Классы, загруженные позже, не отразятся в старом результате.

<?php
$classesBefore = get_declared_classes();
// Автозагрузка нового класса происходит здесь
$classesAfter = get_declared_classes();
// $classesAfter может содержать больше элементов
?>
Попытка передать аргументы

Вызов с аргументами вызовет ошибку в строгом режиме:

<?php
declare(strict_types=1);
$classes = get_declared_classes(true); // Неверно
?>
Fatal error: Uncaught ArgumentCountError: get_declared_classes() expects exactly 0 arguments, 1 given
Сравнение без учета регистра

Имена классов в PHP чувствительны к регистру. Поиск должен быть точным.

<?php
class MyClass {}
$exists = in_array('myclass', get_declared_classes()); // false
?>

Изменения в последних версиях PHP

Функция get_declared_classes() не претерпела значительных изменений в поведении, но её вывод зависит от версии PHP:

PHP 8.0

Добавлены встроенные классы, такие как Stringable (интерфейс) и классы для атрибутов. Изменен порядок вывода: теперь интерфейсы и трейты не смешиваются с классами в этом списке.

PHP 8.1

Появились встроенные enum, которые не включаются в список этой функцией. Для их получения используется get_declared_classes(), так как enum являются классами.

Расширенные примеры

Фильтрация пользовательских классов

Получение только классов, определенных пользователем, исключая встроенные классы PHP:

Пример php
<?php
function get_user_declared_classes() {
    $all = get_declared_classes();
    $internal = [];
    // Предполагаем, что все классы до первого пользовательского - встроенные
    foreach ($all as $class) {
        $reflection = new ReflectionClass($class);
        if ($reflection->isInternal()) {
            $internal[] = $class;
        } else {
            break;
        }
    }
    return array_diff($all, $internal);
}

class UserClassA {}
class UserClassB {}

print_r(get_user_declared_classes());
?>
Array
(
    [75] => UserClassA
    [76] => UserClassB
)
Автоматическая регистрация плагинов

Поиск всех классов, реализующих определенный интерфейс:

Пример php
<?php
interface Plugin {
    public function execute();
}

class LoggerPlugin implements Plugin { public function execute() {} }
class CachePlugin implements Plugin { public function execute() {} }

$plugins = [];
foreach (get_declared_classes() as $class) {
    $reflection = new ReflectionClass($class);
    if ($reflection->implementsInterface('Plugin') && !$reflection->isAbstract()) {
        $plugins[] = new $class();
    }
}

var_dump(count($plugins));
?>
int(2)
Получение классов по пространству имен

Сбор классов, принадлежащих конкретному namespace:

Пример php
<?php
namespace App\Services;

class ServiceA {}
class ServiceB {}

$services = [];
$prefix = 'App\\Services\\';
$prefixLength = strlen($prefix);

foreach (get_declared_classes() as $class) {
    if (strncmp($class, $prefix, $prefixLength) === 0) {
        $services[] = $class;
    }
}

print_r($services);
?>
Array
(
    [0] => App\Services\ServiceA
    [1] => App\Services\ServiceB
)

PHP get_declared_classes function comments

En
Get declared classes Returns an array with the name of the defined classes