Get declared classes: примеры (PHP)
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:
Добавлены встроенные классы, такие как Stringable (интерфейс) и классы для атрибутов. Изменен порядок вывода: теперь интерфейсы и трейты не смешиваются с классами в этом списке.
Появились встроенные enum, которые не включаются в список этой функцией. Для их получения используется get_declared_classes(), так как enum являются классами.
Расширенные примеры
Получение только классов, определенных пользователем, исключая встроенные классы 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
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
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
)