Александр Некрасов · Автономное руководство

PHP: полный мануал с примерами, функциями и ООП

Разделы этой страницы
  1. Reflection PHP: полный справочник классов и методов с практикой
  2. Сначала задача: понять незнакомый клиент API, не вызывая его методы
  3. Что именно находится «внутри»: объект описания вместо копии класса
  4. Официальные команды Reflection в терминале: быстрый отчёт без PHP-скрипта
  5. Расширение встроенных Reflection-классов: когда нужен свой удобный отчёт
  6. Выбор от задачи: какой Reflection-объект создать первым
  7. Реальный выигрыш: маленький контейнер видит зависимости конструктора
  8. Метаданные рядом с кодом: route читается отдельно от исполнения controller
  9. Гидратор и сериализатор: объявление, состояние и значение — три разных вопроса
  10. Красная граница: какие методы только читают, а какие исполняют и меняют
  11. Типы без профессиональной деформации: не превращать string|int в одну строку
  12. Стоимость и кеш: читать метаданные один раз на сборку, а не на каждую строку заказа
  13. Исторические export, устаревшие aliases и поведение по версиям
  14. Полная карта типов официальной ветки Reflection
  15. PropertyHookType: полный обзор класса
  16. Reflection: полный обзор класса
  17. ReflectionAttribute: полный обзор класса
  18. ReflectionClass: полный обзор класса
  19. ReflectionClassConstant: полный обзор класса
  20. ReflectionConstant: полный обзор класса
  21. ReflectionEnum: полный обзор класса
  22. ReflectionEnumBackedCase: полный обзор класса
  23. ReflectionEnumUnitCase: полный обзор класса
  24. ReflectionException: полный обзор класса
  25. ReflectionExtension: полный обзор класса
  26. ReflectionFiber: полный обзор класса
  27. ReflectionFunction: полный обзор класса
  28. ReflectionFunctionAbstract: полный обзор класса
  29. ReflectionGenerator: полный обзор класса
  30. ReflectionIntersectionType: полный обзор класса
  31. ReflectionMethod: полный обзор класса
  32. ReflectionNamedType: полный обзор класса
  33. ReflectionObject: полный обзор класса
  34. ReflectionParameter: полный обзор класса
  35. ReflectionProperty: полный обзор класса
  36. ReflectionReference: полный обзор класса
  37. ReflectionType: полный обзор класса
  38. ReflectionUnionType: полный обзор класса
  39. ReflectionZendExtension: полный обзор класса
  40. Reflector: полный обзор класса
  41. Как читать наследование Reflection и не искать один метод в двадцати местах
  42. Повторяющиеся реальные ошибки: что именно перепутали
  43. Проверка полноты ветки: что считается покрытым
  44. Функции и методы этой темы
  45. Код и руководство с собой
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 74 · От основ до полного API

Reflection PHP: полный справочник классов и методов с практикой

От первого безопасного отчёта о классе до контейнера зависимостей, атрибутов, типов, lazy objects, property hooks, Fiber/Generator и всех 315 официальных страниц Reflection.

Сначала задача: понять незнакомый клиент API, не вызывая его методы

Представьте установленный SDK для банка или Bitrix24. Код вызывает $client->listMethod($params, $method), но версия пакета неизвестна. Reflection может программно прочитать имя класса, список публичных операций, параметры, типы и значения по умолчанию. Пока мы вызываем только методы объектов Reflection, ни один HTTP-запрос клиента не выполняется.

Описание идёт рядом с кодом, но остаётся описанием
  1. Выбираем заранее известный класс или уже созданный объект
  2. ReflectionClass читает его объявление
  3. getMethods возвращает ReflectionMethod, а не результаты методов
  4. getParameters возвращает ReflectionParameter, а не пользовательские данные
  5. CLI-отчёт сравнивается с ожидаемым контрактом версии
  6. Только отдельное явное invoke/newInstance может исполнить код
Прочитать API клиента, не выполнить егоСамостоятельный пример
<?php
declare(strict_types=1);

final class PortalClient
{
    public function listMethod(array $parameters, string $method, int $maxPages = 20): array
    {
        throw new LogicException('Сетевой метод не должен исполняться в этом опыте');
    }
}

$class = new ReflectionClass(PortalClient::class);
$method = $class->getMethod('listMethod');
echo 'операция: ', $method->getName(), "\n";
echo 'обязательных: ', $method->getNumberOfRequiredParameters(), "\n";
foreach ($method->getParameters() as $parameter) {
    echo '$', $parameter->getName(), ': ', (string) $parameter->getType(),
        $parameter->isOptional() ? ' (необязательный)' : ' (обязательный)', "\n";
}
echo "метод клиента не вызывался\n";
Ожидаемый результат
операция: listMethod
обязательных: 2
$parameters: array (обязательный)
$method: string (обязательный)
$maxPages: int (необязательный)
метод клиента не вызывался

Если заменить чтение на $method->invoke(...), тело выполнится и выбросит исключение. В этом и состоит первая граница: получить описание безопаснее, чем автоматически исполнять найденное имя.

Что именно находится «внутри»: объект описания вместо копии класса

Reflection-объект похож на карточку каталога: в нём есть имя, тип, модификаторы и связь с объявлением. Он не является копией исследуемого объекта и не содержит историю его выполнения. ReflectionProperty описывает поле; чтобы читать instance-значение, ему дополнительно нужен конкретный объект.

Обычный элемент программыЕго описаниеЧто можно узнать
Класс / объектReflectionClass / ReflectionObjectродитель, интерфейсы, методы, свойства, атрибуты, возможность создания
Функция / методReflectionFunction / ReflectionMethodпараметры, return type, файл/строки, static/visibility, attributes
ПараметрReflectionParameterимя, позиция, type, default, variadic, ссылка, promotion
СвойствоReflectionPropertytype, visibility, readonly, hooks, initialized/lazy state
ТипReflectionNamedType, UnionType, IntersectionTypeсостав и nullable
ВыполнениеReflectionFiber, ReflectionGeneratorтекущий файл, строка и стек живого приостановленного механизма

Установка и доступность. Reflection входит в ядро PHP: отдельное расширение через Composer или php.ini не требуется. Быструю проверку делают выражением class_exists(ReflectionClass::class), а версию и SAPI фиксируют через PHP_VERSION и PHP_SAPI. CLI, FPM и веб-сервер могут загружать разные расширения и конфигурации, поэтому отчёт из терминала не всегда полностью описывает веб-процесс.

Почему встречаются false и null. Они не всегда означают ошибку: у пользовательской функции нет extension, у класса может не быть конструктора, у внутреннего элемента иногда отсутствуют исходный файл, строки или полные метаданные. Код обязан читать договор конкретного метода и обрабатывать отсутствие данных, а не подставлять выдуманное значение.

Официальные команды Reflection в терминале: быстрый отчёт без PHP-скрипта

В CLI у PHP есть четыре сокращения того же механизма. Они удобны, когда нужно за минуту проверить установленную версию библиотеки на конкретном сервере. Вывод зависит от runtime и загруженных расширений; его нельзя без проверки переносить на другой хост или веб-SAPI.

КомандаЧто описываетПрактическая задача
php --rf strlenфункцию, параметры и return typeУточнить сигнатуру функции именно в установленном PHP.
php --rc DateTimeImmutableкласс, константы, свойства и методыПроверить доступные операции класса перед отладкой legacy-сервера.
php --re jsonрасширение, функции, константы и классыПонять, действительно ли загружен JSON и какой API видит CLI.
php --ri reflectionинформацию расширения в стиле phpinfoСравнить конфигурацию и версию модуля.

Расширение встроенных Reflection-классов: когда нужен свой удобный отчёт

Официальный раздел Extending разрешает наследоваться от встроенных Reflection-классов. Это пригодится для повторяемого отчёта: например, один раз вычислить человекочитаемые модификаторы метода. Если подкласс переопределяет конструктор, сначала вызывают родительский конструктор — именно он связывает объект Reflection с исследуемым объявлением.

Добавить готовое поле visibility к ReflectionMethodСамостоятельный пример
<?php
declare(strict_types=1);

final class ApiMethod extends ReflectionMethod
{
    public array $visibility;

    public function __construct(object|string $class, string $method)
    {
        parent::__construct($class, $method);
        $this->visibility = Reflection::getModifierNames($this->getModifiers());
    }
}

final class CheckoutController
{
    protected function submit(): void {}
}

$method = new ApiMethod(CheckoutController::class, 'submit');
echo $method->getName(), "\n";
echo implode(', ', $method->visibility), "\n";
Ожидаемый результат
submit
protected

В visibility лежит вычисленный отчёт, а не новая видимость метода. Объект Controller не получил публичный submit; обычный вызов по-прежнему подчиняется protected. Без parent::__construct() ReflectionMethod останется несвязанным с реальным методом.

Выбор от задачи: какой Reflection-объект создать первым

Практический вопросНачать сСледующий безопасный шаг
Есть ли у плагина нужный public-метод?ReflectionClass::hasMethodЗатем getMethod и проверка параметров; не invoke.
Что требует конструктор сервиса?ReflectionClass::getConstructorОбработать null; проверить isInstantiable; разобрать ReflectionParameter.
Какие route/validation атрибуты объявлены?ReflectionClass::getAttributesФильтровать по ожидаемому классу; newInstance запускает конструктор.
Можно ли сериализовать typed property?ReflectionProperty::isInitializedСначала состояние и allow-list полей; затем getValue.
Какой вариант string|int реально разрешён?ReflectionFunctionAbstract::getReturnTypeРазличить Named/Union/Intersection и пройти getTypes.
Где остановился Fiber/Generator?ReflectionFiber::getExecutingLineПроверить состояние механизма и не возобновлять его случайно.
Какое расширение загрузило функцию?ReflectionFunctionAbstract::getExtensionNamefalse означает пользовательский код; веб-SAPI может отличаться от CLI.

Реальный выигрыш: маленький контейнер видит зависимости конструктора

Контейнеру дают заранее разрешённое имя сервиса. Он проверяет, можно ли создать класс, получает конструктор, различает отсутствие конструктора и список параметров. У параметра берётся не устаревший getClass, а getType; union/builtin без явного правила контейнер отклоняет. В промышленном контейнере ещё нужны циклы зависимостей, scopes, aliases, factories, attributes и кеш карты.

Собрать Checkout из зарегистрированной зависимостиСамостоятельный пример
<?php
declare(strict_types=1);

final class Logger {}
final class Checkout
{
    public function __construct(public Logger $logger, public string $channel = 'web') {}
}

$services = [Logger::class => new Logger()];
$class = new ReflectionClass(Checkout::class);
if (!$class->isInstantiable()) {
    throw new RuntimeException('Сервис нельзя создать');
}
$constructor = $class->getConstructor();
$arguments = [];
foreach ($constructor?->getParameters() ?? [] as $parameter) {
    $type = $parameter->getType();
    if ($type instanceof ReflectionNamedType && !$type->isBuiltin() && isset($services[$type->getName()])) {
        $arguments[] = $services[$type->getName()];
    } elseif ($parameter->isDefaultValueAvailable()) {
        $arguments[] = $parameter->getDefaultValue();
    } else {
        throw new RuntimeException('Нет правила для $' . $parameter->getName());
    }
}
$checkout = $class->newInstanceArgs($arguments);
echo $checkout::class, "\n";
echo $checkout->logger::class, "\n";
echo $checkout->channel, "\n";
Ожидаемый результат
Checkout
Logger
web

Здесь видно назначение каждого шага. getConstructor() вправе вернуть null; оператор ?-> и ?? [] превращают этот случай в пустой список. Контейнер не пытается догадаться, что означает произвольная строка: использует default или заранее зарегистрированный class type.

Связанные карточки: ReflectionClass::isInstantiable, ReflectionClass::getConstructor, ReflectionFunctionAbstract::getParameters, ReflectionParameter::getType, ReflectionParameter::isDefaultValueAvailable, ReflectionClass::newInstanceArgs.

Метаданные рядом с кодом: route читается отдельно от исполнения controller

Атрибут сам не создаёт маршрут и не проверяет права. Код сборщика находит ReflectionAttribute, читает имя/сырые аргументы, а newInstance() отдельно запускает конструктор класса атрибута. Если нужна только карта, часто достаточно getName/getArguments без создания объекта.

Построить карту маршрутов и не вызвать controllerСамостоятельный пример
<?php
declare(strict_types=1);

#[Attribute(Attribute::TARGET_METHOD)]
final class Route
{
    public function __construct(public string $method, public string $path) {}
}

final class CatalogController
{
    #[Route('GET', '/products')]
    public function products(): array
    {
        throw new LogicException('Controller в сборщике маршрутов не вызывается');
    }
}

$class = new ReflectionClass(CatalogController::class);
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
    foreach ($method->getAttributes(Route::class) as $attribute) {
        $arguments = $attribute->getArguments();
        echo $arguments[0], ' ', $arguments[1], ' -> ', $class->getShortName(), '::', $method->getName(), "\n";
    }
}
Ожидаемый результат
GET /products -> CatalogController::products

Мы сознательно не вызываем products и не создаём Route: getArguments возвращает значения объявления. Валидацию конструктора Route можно получить через newInstance, но это уже исполнение PHP-кода.

Связанные карточки: ReflectionClass::getMethods, ReflectionFunctionAbstract::getAttributes, ReflectionAttribute::getArguments, ReflectionAttribute::getName, ReflectionAttribute::newInstance.

Гидратор и сериализатор: объявление, состояние и значение — три разных вопроса

Наличие свойства не означает, что typed property уже получило значение. Nullable также не инициализирует его автоматически. Сериализатор сначала выбирает разрешённые public-поля, затем проверяет isInitialized на конкретном объекте и лишь потом getValue. Секреты не должны попадать в вывод из-за автоматического обхода private.

Пропустить неинициализированное поле и вывести ожидаемые public-данныеСамостоятельный пример
<?php
declare(strict_types=1);

final class ProductView
{
    public string $sku = 'A-7';
    public ?string $note;
    private string $token = 'secret';
}

$product = new ProductView();
$class = new ReflectionClass($product);
$output = [];
foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $property) {
    if (!$property->isInitialized($product)) {
        echo 'пропущено: ', $property->getName(), "\n";
        continue;
    }
    $output[$property->getName()] = $property->getValue($product);
}
echo json_encode($output, JSON_UNESCAPED_UNICODE), "\n";
Ожидаемый результат
пропущено: note
{"sku":"A-7"}

token не выбран фильтром public и не раскрыт. note допускает null, но остаётся неинициализированным, потому что значение ему не присваивали.

Связанные карточки: ReflectionClass::getProperties, ReflectionProperty::isInitialized, ReflectionProperty::getValue, ReflectionProperty::isPublic.

Красная граница: какие методы только читают, а какие исполняют и меняют

ГруппаПримерыЧто может произойти
Чтение метаданныхgetName, getType, getParameters, isFinal, hasMethodВозвращается описание; автозагрузка строки-класса всё равно может выполнить loader.
СозданиеnewInstance*, ReflectionAttribute::newInstanceВыполняется конструктор класса/атрибута, возможны I/O и исключения.
ВызовReflectionFunction/Method::invoke*Выполняется произвольное тело функции/метода с его побочными эффектами.
ЗаписьReflectionProperty::setValue/setRawValue*Меняется объект; типы, readonly и hooks имеют разные правила.
Lazy APInewLazy*, initialize*, resetAsLazy*Callback выполняется по триггеру; сериализация и свойства могут инициировать работу.
Диагностический выводReflectionExtension::info, __toStringПишется информация окружения; не отправляйте её публичному клиенту.

Типы без профессиональной деформации: не превращать string|int в одну строку

getType возвращает объект или null. Один тип представлен ReflectionNamedType; объединение — ReflectionUnionType; пересечение — ReflectionIntersectionType. Строковое приведение удобно для отчёта, но для логики контейнера нужно различать подклассы и пройти getTypes. allowsNull — отдельный вопрос.

Разобрать union на частиСамостоятельный пример
<?php
declare(strict_types=1);

function findProduct(string|int $key): array { return []; }

$parameter = (new ReflectionFunction('findProduct'))->getParameters()[0];
$type = $parameter->getType();
echo $type::class, "\n";
if ($type instanceof ReflectionUnionType) {
    foreach ($type->getTypes() as $part) {
        echo $part->getName(), ': ', $part->isBuiltin() ? 'builtin' : 'class', "\n";
    }
}
Ожидаемый результат
ReflectionUnionType
string: builtin
int: builtin

Union — не массив значений и не автоматическое преобразование. Он сообщает, что вызывающий код вправе передать одно из перечисленных значений; функция всё равно решает, как различить ID и артикул.

Связанные карточки: ReflectionParameter::getType, ReflectionType::allowsNull, ReflectionUnionType::getTypes, ReflectionNamedType::getName, ReflectionNamedType::isBuiltin.

Стоимость и кеш: читать метаданные один раз на сборку, а не на каждую строку заказа

Reflection — runtime-работа. Для одной CLI-диагностики цена обычно несущественна. Роутер или контейнер может просканировать сотни классов; тогда карту строят один раз, валидируют, сохраняют в память/сгенерированный PHP-файл и сбрасывают при изменении кода. Не объявляйте Reflection «медленным» без профиля: главная ошибка — повторять одинаковое сканирование внутри горячего цикла.

Построить схему один раз и использовать много разСамостоятельный пример
<?php
declare(strict_types=1);

final class PriceService
{
    public function total(int $price, int $quantity): int { return $price * $quantity; }
}

$builds = 0;
$schema = null;
$getSchema = static function () use (&$schema, &$builds): array {
    if ($schema !== null) return $schema;
    $builds++;
    $method = new ReflectionMethod(PriceService::class, 'total');
    return $schema = array_map(
        static fn (ReflectionParameter $p): string => $p->getName() . ':' . $p->getType(),
        $method->getParameters(),
    );
};

echo implode(', ', $getSchema()), "\n";
echo implode(', ', $getSchema()), "\n";
echo 'сборок: ', $builds, "\n";
Ожидаемый результат
price:int, quantity:int
price:int, quantity:int
сборок: 1

Closure хранит локальный кеш в переменной schema. В долгоживущем worker следите за версией кода и памятью; в обычном PHP-FPM кеш процесса не равен общему постоянному кешу всех workers.

Измерять время можно средствами hrtime(), но сравнивайте сценарий целиком и прогревайте одинаковые пути.

Исторические export, устаревшие aliases и поведение по версиям

Полный мануал сохраняет старые страницы, потому что они встречаются в legacy-коде и поиске ошибок. Это не означает рекомендацию запускать удалённый метод на PHP 8.5. Карточка показывает последнюю официальную сигнатуру, границу версии и современную замену с видимым результатом.

Legacy APIГраницаЗамена
Reflection*::export()Удалены в PHP 8.0Создать конкретный Reflection-объект; читать нужные поля либо контролируемо использовать (string)$reflection.
ReflectionClass::isIterateable()Старое написание сохранено как aliasНовый код использует isIterable().
ReflectionParameter::getClass/isArray/isCallableУстарели с PHP 8.0getType() + проверка ReflectionNamedType/UnionType/IntersectionType.
setAccessible()Не влияет с PHP 8.1, deprecated с PHP 8.5Reflection уже может читать private; обычная видимость объекта не меняется.
ReflectionFunction::isDisabled()Устарел с PHP 8.0Disabled function нельзя создать как ReflectionFunction; обрабатывайте ReflectionException/конфигурацию.

Полная карта типов официальной ветки Reflection

Ниже идут отдельные разделы каждого официального класса/интерфейса/enum. Внутри — свойства, константы и ссылки на все страницы методов. Общий метод находится у родительского Reflection-типа и не дублируется отдельной карточкой каждого наследника.

ТипНазначение
PropertyHookTypeEnum Get/Set для property hooks PHP 8.4+
ReflectionБитовые модификаторы и исторический корневой API
ReflectionAttributeОписание одного атрибута до создания его объекта
ReflectionClassКласс, интерфейс, trait или enum как программно читаемое описание
ReflectionClassConstantОдна константа класса или enum-case
ReflectionConstantГлобальная или namespaced-константа
ReflectionEnumEnum, его cases и backing type
ReflectionEnumBackedCaseBacked case и его scalar value
ReflectionEnumUnitCaseОдин unit/backed case как объявление
ReflectionExceptionОшибка неизвестного или неподходящего Reflection-элемента
ReflectionExtensionОбычное расширение PHP и его функции, классы, INI
ReflectionFiberМесто и стек приостановленного Fiber
ReflectionFunctionКонкретная функция или Closure; invoke действительно исполняет её
ReflectionFunctionAbstractОбщие сведения функций и методов
ReflectionGeneratorТочка остановки и стек живого Generator
ReflectionIntersectionTypeПересечение A&B
ReflectionMethodМетод, видимость, прототип и контролируемый вызов
ReflectionNamedTypeОдин именованный builtin/class type
ReflectionObjectReflectionClass, созданный строго из конкретного объекта
ReflectionParameterПараметр: имя, тип, default, ссылка, variadic, атрибуты
ReflectionPropertyСвойство, состояние, hooks, lazy/raw операции
ReflectionReferenceДиагностика PHP-ссылок внутри массива
ReflectionTypeОбщий договор типов и nullable
ReflectionUnionTypeОбъединение A|B
ReflectionZendExtensionZend-расширение движка, например OPcache
ReflectorОбщий интерфейс Reflection-описаний

PropertyHookType: полный обзор класса

Enum Get/Set для property hooks PHP 8.4+

Свойство типаЗначение в PHP 8.5.11
Видenum
Родительнет
ИнтерфейсыBackedEnum, UnitEnum
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.
$valuestring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
PropertyHookType::GetPropertyHookType::Get; enum-case
PropertyHookType::SetPropertyHookType::Set; enum-case

Методы cases(), from() и tryFrom() приходят от enum-договоров; в ReflectionProperty обычно передают конкретный PropertyHookType::Get или ::Set.

CaseBacking value
PropertyHookType::Getget
PropertyHookType::Setset

У этого типа нет собственных страниц методов в ветке Reflection; его роль раскрыта в таблице и связанных исключениях.

Официальный класс: PropertyHookType. Количество собственных методов текущего runtime: 3. Унаследованные методы читаются в классе, где определён общий договор.

Reflection: полный обзор класса

Битовые модификаторы и исторический корневой API

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
Интерфейсынет
Создаётся напрямуюда
Клонируетсяда

Все официальные страницы методов

  • Reflection::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • Reflection::getModifierNames — Расшифровать битовую маску public, static, final и других модификаторов в список имён.

Официальный класс: Reflection. Количество собственных методов текущего runtime: 1. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionAttribute: полный обзор класса

Описание одного атрибута до создания его объекта

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
ReflectionAttribute::IS_INSTANCEOF2; флаг или граница API

Все официальные страницы методов

  • ReflectionAttribute::__construct — Создать описание Attribute по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionAttribute::getArguments — Получить arguments из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionAttribute::getName — Получить name из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionAttribute::getTarget — Получить target из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionAttribute::isRepeated — Ответить на узкий вопрос «is repeated» и не делать из bool более широких выводов о корректности программы.
  • ReflectionAttribute::newInstance — Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

Официальный класс: ReflectionAttribute. Количество собственных методов текущего runtime: 8. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionClass: полный обзор класса

Класс, интерфейс, trait или enum как программно читаемое описание

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
ReflectionClass::IS_EXPLICIT_ABSTRACT64; флаг или граница API
ReflectionClass::IS_FINAL32; флаг или граница API
ReflectionClass::IS_IMPLICIT_ABSTRACT16; флаг или граница API
ReflectionClass::IS_READONLY65536; флаг или граница API
ReflectionClass::SKIP_DESTRUCTOR16; флаг или граница API
ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE8; флаг или граница API

Все официальные страницы методов

  • ReflectionClass::__construct — Создать описание Class по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionClass::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionClass::getAttributes — Получить attributes из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getConstant — Получить constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getConstants — Получить constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getConstructor — Получить constructor из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getDefaultProperties — Получить default properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getDocComment — Получить doc comment из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getEndLine — Получить end line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getExtension — Получить extension из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getExtensionName — Получить extension name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getFileName — Получить file name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getInterfaceNames — Получить interface names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getInterfaces — Получить interfaces из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getLazyInitializer — Получить lazy initializer из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getMethod — Получить method из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getMethods — Получить methods из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getModifiers — Получить modifiers из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getName — Получить name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getNamespaceName — Получить namespace name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getParentClass — Получить parent class из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getProperties — Получить properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getProperty — Получить property из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getReflectionConstant — Получить reflection constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getReflectionConstants — Получить reflection constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getShortName — Получить short name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getStartLine — Получить start line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getStaticProperties — Получить static properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getStaticPropertyValue — Получить static property value из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getTraitAliases — Получить trait aliases из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getTraitNames — Получить trait names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::getTraits — Получить traits из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClass::hasConstant — Проверить наличие constant до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionClass::hasMethod — Проверить наличие method до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionClass::hasProperty — Проверить наличие property до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionClass::implementsInterface — Применить ReflectionClass::implementsInterface к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionClass::initializeLazyObject — Применить ReflectionClass::initializeLazyObject к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionClass::inNamespace — Применить ReflectionClass::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionClass::isAbstract — Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isAnonymous — Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isCloneable — Ответить на узкий вопрос «is cloneable» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isEnum — Ответить на узкий вопрос «is enum» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isFinal — Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isInstance — Ответить на узкий вопрос «is instance» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isInstantiable — Ответить на узкий вопрос «is instantiable» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isInterface — Ответить на узкий вопрос «is interface» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isInternal — Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isIterable — Ответить на узкий вопрос «is iterable» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isIterateable — Ответить на узкий вопрос «is iterateable» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isReadOnly — Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isSubclassOf — Ответить на узкий вопрос «is subclass of» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isTrait — Ответить на узкий вопрос «is trait» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isUninitializedLazyObject — Ответить на узкий вопрос «is uninitialized lazy object» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::isUserDefined — Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClass::markLazyObjectAsInitialized — Применить ReflectionClass::markLazyObjectAsInitialized к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionClass::newInstance — Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.
  • ReflectionClass::newInstanceArgs — Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.
  • ReflectionClass::newInstanceWithoutConstructor — Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.
  • ReflectionClass::newLazyGhost — Создать объект, состояние которого заполнится только при первом наблюдении.
  • ReflectionClass::newLazyProxy — Создать заместитель, который по требованию получит настоящий объект из фабрики.
  • ReflectionClass::resetAsLazyGhost — Очистить совместимый объект и снова сделать его ленивым ghost-объектом.
  • ReflectionClass::resetAsLazyProxy — Очистить совместимый объект и снова связать его с ленивой фабрикой proxy.
  • ReflectionClass::setStaticPropertyValue — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionClass::__toString — Получить встроенное текстовое диагностическое представление ReflectionClass; формат не является стабильным API.

Официальный класс: ReflectionClass. Количество собственных методов текущего runtime: 64. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionClassConstant: полный обзор класса

Одна константа класса или enum-case

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$classstring; это метаданные, а не одноимённое поле исследуемого объекта.
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
ReflectionClassConstant::IS_FINAL32; флаг или граница API
ReflectionClassConstant::IS_PRIVATE4; флаг или граница API
ReflectionClassConstant::IS_PROTECTED2; флаг или граница API
ReflectionClassConstant::IS_PUBLIC1; флаг или граница API

Все официальные страницы методов

  • ReflectionClassConstant::__construct — Создать описание ClassConstant по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionClassConstant::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionClassConstant::getAttributes — Получить attributes из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getDeclaringClass — Получить declaring class из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getDocComment — Получить doc comment из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getModifiers — Получить modifiers из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getName — Получить name из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getType — Получить type из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::getValue — Получить value из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionClassConstant::hasType — Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionClassConstant::isDeprecated — Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::isEnumCase — Ответить на узкий вопрос «is enum case» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::isFinal — Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::isPrivate — Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::isProtected — Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::isPublic — Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.
  • ReflectionClassConstant::__toString — Получить встроенное текстовое диагностическое представление ReflectionClassConstant; формат не является стабильным API.

Официальный класс: ReflectionClassConstant. Количество собственных методов текущего runtime: 17. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionConstant: полный обзор класса

Глобальная или namespaced-константа

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Все официальные страницы методов

  • ReflectionConstant::__construct — Создать описание Constant по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionConstant::getAttributes — Получить attributes из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getExtension — Получить extension из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getExtensionName — Получить extension name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getFileName — Получить file name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getName — Получить name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getNamespaceName — Получить namespace name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getShortName — Получить short name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::getValue — Получить value из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionConstant::isDeprecated — Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.
  • ReflectionConstant::__toString — Получить встроенное текстовое диагностическое представление ReflectionConstant; формат не является стабильным API.

Официальный класс: ReflectionConstant. Количество собственных методов текущего runtime: 11. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionEnum: полный обзор класса

Enum, его cases и backing type

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionClass
ИнтерфейсыReflector, Stringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionEnum::__construct — Создать описание Enum по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionEnum::getBackingType — Получить backing type из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionEnum::getCase — Получить case из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionEnum::getCases — Получить cases из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionEnum::hasCase — Проверить наличие case до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionEnum::isBacked — Ответить на узкий вопрос «is backed» и не делать из bool более широких выводов о корректности программы.

Официальный класс: ReflectionEnum. Количество собственных методов текущего runtime: 6. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionEnumBackedCase: полный обзор класса

Backed case и его scalar value

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionEnumUnitCase
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionEnumBackedCase::__construct — Создать описание EnumBackedCase по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionEnumBackedCase::getBackingValue — Получить backing value из уже выбранного ReflectionEnumBackedCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionEnumBackedCase. Количество собственных методов текущего runtime: 2. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionEnumUnitCase: полный обзор класса

Один unit/backed case как объявление

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionClassConstant
ИнтерфейсыReflector, Stringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionEnumUnitCase::__construct — Создать описание EnumUnitCase по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionEnumUnitCase::getEnum — Получить enum из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionEnumUnitCase::getValue — Получить value из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionEnumUnitCase. Количество собственных методов текущего runtime: 3. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionException: полный обзор класса

Ошибка неизвестного или неподходящего Reflection-элемента

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительException
ИнтерфейсыThrowable, Stringable
Создаётся напрямуюда
Клонируетсянет

У этого типа нет собственных страниц методов в ветке Reflection; его роль раскрыта в таблице и связанных исключениях.

Официальный класс: ReflectionException. Количество собственных методов текущего runtime: 0. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionExtension: полный обзор класса

Обычное расширение PHP и его функции, классы, INI

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Все официальные страницы методов

  • ReflectionExtension::__clone — Проверить правила клонирования объекта ReflectionExtension и не путать описание с копией исследуемого объекта.
  • ReflectionExtension::__construct — Создать описание Extension по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionExtension::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionExtension::getClasses — Получить classes из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getClassNames — Получить class names из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getConstants — Получить constants из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getDependencies — Получить dependencies из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getFunctions — Получить functions из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getINIEntries — Получить i n i entries из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getName — Получить name из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::getVersion — Получить version из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionExtension::info — Вывести диагностическую информацию расширения; этот метод пишет вывод, а не возвращает массив.
  • ReflectionExtension::isPersistent — Ответить на узкий вопрос «is persistent» и не делать из bool более широких выводов о корректности программы.
  • ReflectionExtension::isTemporary — Ответить на узкий вопрос «is temporary» и не делать из bool более широких выводов о корректности программы.
  • ReflectionExtension::__toString — Получить встроенное текстовое диагностическое представление ReflectionExtension; формат не является стабильным API.

Официальный класс: ReflectionExtension. Количество собственных методов текущего runtime: 14. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionFiber: полный обзор класса

Место и стек приостановленного Fiber

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
Интерфейсынет
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionFiber::__construct — Создать описание Fiber по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionFiber::getCallable — Получить callable из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFiber::getExecutingFile — Получить executing file из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFiber::getExecutingLine — Получить executing line из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFiber::getFiber — Получить fiber из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFiber::getTrace — Получить trace из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionFiber. Количество собственных методов текущего runtime: 6. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionFunction: полный обзор класса

Конкретная функция или Closure; invoke действительно исполняет её

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionFunctionAbstract
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Константы и маски

КонстантаЗначение / применение
ReflectionFunction::IS_DEPRECATED2048; флаг или граница API

Все официальные страницы методов

  • ReflectionFunction::__construct — Создать описание Function по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionFunction::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionFunction::getClosure — Получить closure из уже выбранного ReflectionFunction и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunction::invoke — Действительно вызвать отражённую функцию с позиционными аргументами.
  • ReflectionFunction::invokeArgs — Действительно вызвать отражённую функцию, передав аргументы массивом.
  • ReflectionFunction::isAnonymous — Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunction::isDisabled — Ответить на узкий вопрос «is disabled» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunction::__toString — Получить встроенное текстовое диагностическое представление ReflectionFunction; формат не является стабильным API.

Официальный класс: ReflectionFunction. Количество собственных методов текущего runtime: 7. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionFunctionAbstract: полный обзор класса

Общие сведения функций и методов

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыReflector, Stringable
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Все официальные страницы методов

  • ReflectionFunctionAbstract::isStatic — Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::__clone — Проверить правила клонирования объекта ReflectionFunctionAbstract и не путать описание с копией исследуемого объекта.
  • ReflectionFunctionAbstract::getAttributes — Получить attributes из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getClosureCalledClass — Получить closure called class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getClosureScopeClass — Получить closure scope class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getClosureThis — Получить closure this из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getClosureUsedVariables — Получить closure used variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getDocComment — Получить doc comment из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getEndLine — Получить end line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getExtension — Получить extension из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getExtensionName — Получить extension name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getFileName — Получить file name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getName — Получить name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getNamespaceName — Получить namespace name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getNumberOfParameters — Получить number of parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getNumberOfRequiredParameters — Получить number of required parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getParameters — Получить parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getReturnType — Получить return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getShortName — Получить short name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getStartLine — Получить start line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getStaticVariables — Получить static variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::getTentativeReturnType — Получить tentative return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionFunctionAbstract::hasReturnType — Проверить наличие return type до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionFunctionAbstract::hasTentativeReturnType — Проверить наличие tentative return type до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionFunctionAbstract::inNamespace — Применить ReflectionFunctionAbstract::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionFunctionAbstract::isClosure — Ответить на узкий вопрос «is closure» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::isDeprecated — Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::isGenerator — Ответить на узкий вопрос «is generator» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::isInternal — Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::isUserDefined — Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::isVariadic — Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::returnsReference — Ответить на узкий вопрос «returns reference» и не делать из bool более широких выводов о корректности программы.
  • ReflectionFunctionAbstract::__toString — Получить встроенное текстовое диагностическое представление ReflectionFunctionAbstract; формат не является стабильным API.

Официальный класс: ReflectionFunctionAbstract. Количество собственных методов текущего runtime: 32. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionGenerator: полный обзор класса

Точка остановки и стек живого Generator

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
Интерфейсынет
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionGenerator::__construct — Создать описание Generator по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionGenerator::getExecutingFile — Получить executing file из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::getExecutingGenerator — Получить executing generator из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::getExecutingLine — Получить executing line из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::getFunction — Получить function из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::getThis — Получить this из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::getTrace — Получить trace из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionGenerator::isClosed — Ответить на узкий вопрос «is closed» и не делать из bool более широких выводов о корректности программы.

Официальный класс: ReflectionGenerator. Количество собственных методов текущего runtime: 8. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionIntersectionType: полный обзор класса

Пересечение A&B

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionType
ИнтерфейсыStringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionIntersectionType::getTypes — Получить types из уже выбранного ReflectionIntersectionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionIntersectionType. Количество собственных методов текущего runtime: 1. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionMethod: полный обзор класса

Метод, видимость, прототип и контролируемый вызов

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionFunctionAbstract
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$classstring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
ReflectionMethod::IS_ABSTRACT64; флаг или граница API
ReflectionMethod::IS_FINAL32; флаг или граница API
ReflectionMethod::IS_PRIVATE4; флаг или граница API
ReflectionMethod::IS_PROTECTED2; флаг или граница API
ReflectionMethod::IS_PUBLIC1; флаг или граница API
ReflectionMethod::IS_STATIC16; флаг или граница API

Все официальные страницы методов

  • ReflectionMethod::__construct — Создать описание Method по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionMethod::createFromMethodName — Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.
  • ReflectionMethod::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionMethod::getClosure — Получить closure из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionMethod::getDeclaringClass — Получить declaring class из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionMethod::getModifiers — Получить modifiers из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionMethod::getPrototype — Получить prototype из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionMethod::hasPrototype — Проверить наличие prototype до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionMethod::invoke — Действительно вызвать отражённый метод у выбранного объекта.
  • ReflectionMethod::invokeArgs — Действительно вызвать отражённый метод, передав аргументы массивом.
  • ReflectionMethod::isAbstract — Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isConstructor — Ответить на узкий вопрос «is constructor» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isDestructor — Ответить на узкий вопрос «is destructor» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isFinal — Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isPrivate — Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isProtected — Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::isPublic — Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.
  • ReflectionMethod::setAccessible — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionMethod::__toString — Получить встроенное текстовое диагностическое представление ReflectionMethod; формат не является стабильным API.

Официальный класс: ReflectionMethod. Количество собственных методов текущего runtime: 18. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionNamedType: полный обзор класса

Один именованный builtin/class type

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionType
ИнтерфейсыStringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionNamedType::getName — Получить name из уже выбранного ReflectionNamedType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionNamedType::isBuiltin — Ответить на узкий вопрос «is builtin» и не делать из bool более широких выводов о корректности программы.

Официальный класс: ReflectionNamedType. Количество собственных методов текущего runtime: 2. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionObject: полный обзор класса

ReflectionClass, созданный строго из конкретного объекта

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionClass
ИнтерфейсыReflector, Stringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionObject::__construct — Создать описание Object по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionObject::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

Официальный класс: ReflectionObject. Количество собственных методов текущего runtime: 1. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionParameter: полный обзор класса

Параметр: имя, тип, default, ссылка, variadic, атрибуты

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Все официальные страницы методов

  • ReflectionParameter::allowsNull — Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::canBePassedByValue — Ответить на узкий вопрос «can be passed by value» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::__clone — Проверить правила клонирования объекта ReflectionParameter и не путать описание с копией исследуемого объекта.
  • ReflectionParameter::__construct — Создать описание Parameter по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionParameter::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionParameter::getAttributes — Получить attributes из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getClass — Получить class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getDeclaringClass — Получить declaring class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getDeclaringFunction — Получить declaring function из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getDefaultValue — Получить default value из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getDefaultValueConstantName — Получить default value constant name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getName — Получить name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getPosition — Получить position из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::getType — Получить type из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionParameter::hasType — Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionParameter::isArray — Ответить на узкий вопрос «is array» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isCallable — Ответить на узкий вопрос «is callable» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isDefaultValueAvailable — Ответить на узкий вопрос «is default value available» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isDefaultValueConstant — Ответить на узкий вопрос «is default value constant» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isOptional — Ответить на узкий вопрос «is optional» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isPassedByReference — Ответить на узкий вопрос «is passed by reference» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isPromoted — Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::isVariadic — Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.
  • ReflectionParameter::__toString — Получить встроенное текстовое диагностическое представление ReflectionParameter; формат не является стабильным API.

Официальный класс: ReflectionParameter. Количество собственных методов текущего runtime: 23. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionProperty: полный обзор класса

Свойство, состояние, hooks, lazy/raw операции

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$classstring; это метаданные, а не одноимённое поле исследуемого объекта.
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Константы и маски

КонстантаЗначение / применение
ReflectionProperty::IS_ABSTRACT64; флаг или граница API
ReflectionProperty::IS_FINAL32; флаг или граница API
ReflectionProperty::IS_PRIVATE4; флаг или граница API
ReflectionProperty::IS_PRIVATE_SET4096; флаг или граница API
ReflectionProperty::IS_PROTECTED2; флаг или граница API
ReflectionProperty::IS_PROTECTED_SET2048; флаг или граница API
ReflectionProperty::IS_PUBLIC1; флаг или граница API
ReflectionProperty::IS_READONLY128; флаг или граница API
ReflectionProperty::IS_STATIC16; флаг или граница API
ReflectionProperty::IS_VIRTUAL512; флаг или граница API

Все официальные страницы методов

  • ReflectionProperty::__clone — Проверить правила клонирования объекта ReflectionProperty и не путать описание с копией исследуемого объекта.
  • ReflectionProperty::__construct — Создать описание Property по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionProperty::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionProperty::getAttributes — Получить attributes из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getDeclaringClass — Получить declaring class из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getDefaultValue — Получить default value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getDocComment — Получить doc comment из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getHook — Получить hook из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getHooks — Получить hooks из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getMangledName — Получить mangled name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getModifiers — Получить modifiers из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getName — Получить name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getRawValue — Получить raw value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getSettableType — Получить settable type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getType — Получить type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::getValue — Получить value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionProperty::hasDefaultValue — Проверить наличие default value до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionProperty::hasHook — Проверить наличие hook до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionProperty::hasHooks — Проверить наличие hooks до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionProperty::hasType — Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.
  • ReflectionProperty::isAbstract — Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isDefault — Ответить на узкий вопрос «is default» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isDynamic — Ответить на узкий вопрос «is dynamic» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isFinal — Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isInitialized — Ответить на узкий вопрос «is initialized» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isLazy — Ответить на узкий вопрос «is lazy» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isPrivate — Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isPrivateSet — Ответить на узкий вопрос «is private set» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isPromoted — Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isProtected — Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isProtectedSet — Ответить на узкий вопрос «is protected set» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isPublic — Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isReadOnly — Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isStatic — Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::isVirtual — Ответить на узкий вопрос «is virtual» и не делать из bool более широких выводов о корректности программы.
  • ReflectionProperty::setAccessible — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionProperty::setRawValue — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionProperty::setRawValueWithoutLazyInitialization — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionProperty::setValue — Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.
  • ReflectionProperty::skipLazyInitialization — Применить ReflectionProperty::skipLazyInitialization к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionProperty::__toString — Получить встроенное текстовое диагностическое представление ReflectionProperty; формат не является стабильным API.

Официальный класс: ReflectionProperty. Количество собственных методов текущего runtime: 40. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionReference: полный обзор класса

Диагностика PHP-ссылок внутри массива

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
Интерфейсынет
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Все официальные страницы методов

  • ReflectionReference::__construct — Понять, почему ReflectionReference нельзя создать напрямую и где взять корректный экземпляр.
  • ReflectionReference::fromArrayElement — Применить ReflectionReference::fromArrayElement к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.
  • ReflectionReference::getId — Получить id из уже выбранного ReflectionReference и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionReference. Количество собственных методов текущего runtime: 4. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionType: полный обзор класса

Общий договор типов и nullable

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Все официальные страницы методов

  • ReflectionType::allowsNull — Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.
  • ReflectionType::__toString — Получить встроенное текстовое диагностическое представление ReflectionType; формат не является стабильным API.

Официальный класс: ReflectionType. Количество собственных методов текущего runtime: 3. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionUnionType: полный обзор класса

Объединение A|B

Свойство типаЗначение в PHP 8.5.11
Видclass
РодительReflectionType
ИнтерфейсыStringable
Создаётся напрямуюда
Клонируетсянет

Все официальные страницы методов

  • ReflectionUnionType::getTypes — Получить types из уже выбранного ReflectionUnionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Официальный класс: ReflectionUnionType. Количество собственных методов текущего runtime: 1. Унаследованные методы читаются в классе, где определён общий договор.

ReflectionZendExtension: полный обзор класса

Zend-расширение движка, например OPcache

Свойство типаЗначение в PHP 8.5.11
Видclass
Родительнет
ИнтерфейсыStringable, Reflector
Создаётся напрямуюда
Клонируетсянет

Открытые свойства описания

СвойствоТип и граница
$namestring; это метаданные, а не одноимённое поле исследуемого объекта.

Все официальные страницы методов

  • ReflectionZendExtension::__clone — Проверить правила клонирования объекта ReflectionZendExtension и не путать описание с копией исследуемого объекта.
  • ReflectionZendExtension::__construct — Создать описание ZendExtension по конкретному имени или объекту и получить ошибку для неизвестной цели.
  • ReflectionZendExtension::export — Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.
  • ReflectionZendExtension::getAuthor — Получить author из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionZendExtension::getCopyright — Получить copyright из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionZendExtension::getName — Получить name из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionZendExtension::getURL — Получить u r l из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionZendExtension::getVersion — Получить version из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.
  • ReflectionZendExtension::__toString — Получить встроенное текстовое диагностическое представление ReflectionZendExtension; формат не является стабильным API.

Официальный класс: ReflectionZendExtension. Количество собственных методов текущего runtime: 8. Унаследованные методы читаются в классе, где определён общий договор.

Reflector: полный обзор класса

Общий интерфейс Reflection-описаний

Свойство типаЗначение в PHP 8.5.11
Видinterface
Родительнет
ИнтерфейсыStringable
Создаётся напрямуюнет либо только специальной фабрикой
Клонируетсянет

Все официальные страницы методов

  • Reflector::export — Историческая статическая выгрузка Reflection, удалённая из PHP; перейти на явные объекты и __toString.

Официальный класс: Reflector. Количество собственных методов текущего runtime: 0. Унаследованные методы читаются в классе, где определён общий договор.

Как читать наследование Reflection и не искать один метод в двадцати местах

Базовый договорНаследники / смысл
ReflectorОбщий маркер Reflection-описаний.
ReflectionFunctionAbstractReflectionFunction и ReflectionMethod получают общие getParameters/getReturnType/source/attribute методы.
ReflectionTypeNamedType, UnionType и IntersectionType.
ReflectionClassReflectionObject и ReflectionEnum; ReflectionEnum далее специализируют case-типы.
ReflectionClassConstantReflectionEnumUnitCase и ReflectionEnumBackedCase дополняют описание case.

Например, официальная страница ReflectionFunctionAbstract::getAttributes() относится и к ReflectionMethod. В ранее написанном практическом разделе она сохранена как ReflectionMethod::getAttributes. Здесь ссылка ведёт к одному подробному договору, а не создаёт несовместимые копии.

Повторяющиеся реальные ошибки: что именно перепутали

СимптомПричинаИсправление мышления
getConstructor()->getParameters падаетgetConstructor вернул nullСначала обработать отсутствие конструктора; это нормальный результат.
После setAccessible обычное $object->private всё ещё падаетReflection не переписывает видимость PHP-выраженияЧитать через ReflectionProperty; на PHP 8.1+ сам флаг уже не нужен.
setValue меняет не тот объект / read-only ошибкаПередали ReflectionObject вместо целевого domain objectПервый аргумент instance-property — объект, чьё поле меняется.
attribute instanceof Constraint всегда falseПолучен ReflectionAttribute, а не объект атрибутаСначала проверить getName/getArguments; newInstance только если нужно исполнить constructor.
Контейнер не понимает union или scalarТип не даёт значения или policy автоматическиЯвные factories/config/default; не угадывать строку или interface.
Reflection-сканирование на каждой записи медленноеОдинаковую схему строят в горячем циклеПостроить/проверить один раз и кешировать с версией кода.

Обсуждения используются как карта проблем, а контракт и версии берутся из официальных страниц PHP и php-src. Код ответов не копируется.

Проверка полноты ветки: что считается покрытым

ИнвентарьКоличествоКак представлен
Официальные узлы book.reflection315Все URL сохранены в источниках главы.
Страницы классов/интерфейсов/enum26Отдельный обзор каждого типа, свойств, констант и методов.
Тематические страницы3Examples, Extending и вводная раскрыты практическими сценариями и границами.
Страницы методов286280 новых карточек + 6 сохранённых подробных карточек.
Runtime PHP8.5.1126 типов; actual signatures/properties/constants зафиксированы через Reflection.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

ReflectionFunctionAbstract::isStaticОтветить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isStatic(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isStaticСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction(static fn (): int => 1);
$value = $r->isStatic();
echo 'isStatic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isStatic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

Reflection::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function Reflection::export(Reflector $reflector, bool $return = false): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат Reflection::exportСамостоятельный пример
<?php
declare(strict_types=1);

$reflection = new ReflectionClass(DateTimeImmutable::class);
echo "Reflection::export удалён\n";
echo 'современная замена: ', $reflection->getShortName(), "\n";
Ожидаемый результат
Reflection::export удалён
современная замена: DateTimeImmutable

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

Reflection::getModifierNamesРасшифровать битовую маску public, static, final и других модификаторов в список имён.

PHP 5, PHP 7, PHP 8 · Reflection

public static function Reflection::getModifierNames(int $modifiers): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Расшифровать битовую маску public, static, final и других модификаторов в список имён.

ПараметрЧто именно передать
$modifiers
int
Битовая маска модификаторов Reflection, которую нужно расшифровать в имена.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат Reflection::getModifierNamesСамостоятельный пример
<?php
declare(strict_types=1);

$mask = ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_FINAL;
$names = Reflection::getModifierNames($mask);
sort($names);
echo implode(', ', $names), "\n";
Ожидаемый результат
final, public

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Расшифровать битовую маску public, static, final и других модификаторов в список имён. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionAttribute::__constructСоздать описание Attribute по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8 · Reflection

public function ReflectionAttribute::__construct(): mixed

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Создать описание Attribute по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionAttribute::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$method = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$r = $method->getAttributes(Demo\ReflectionLab\Label::class)[0];
echo 'экземпляр получен только через getAttributes: ', $r::class, "\n";
}
Ожидаемый результат
экземпляр получен только через getAttributes: ReflectionAttribute

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Attribute по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionAttribute::getArgumentsПолучить arguments из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionAttribute::getArguments(): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить arguments из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionAttribute::getArgumentsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$method = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$r = $method->getAttributes(Demo\ReflectionLab\Label::class)[0];
$value = $r->getArguments();
echo 'getArguments: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getArguments: array(1): route

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить arguments из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionAttribute::getNameПолучить name из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionAttribute::getName(): string

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить name из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionAttribute::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$method = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$r = $method->getAttributes(Demo\ReflectionLab\Label::class)[0];
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: Demo\ReflectionLab\Label

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionAttribute::getTargetПолучить target из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionAttribute::getTarget(): int

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить target из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionAttribute::getTargetСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$method = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$r = $method->getAttributes(Demo\ReflectionLab\Label::class)[0];
$value = $r->getTarget();
echo 'getTarget: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTarget: 4

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить target из уже выбранного ReflectionAttribute и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionAttribute::isRepeatedОтветить на узкий вопрос «is repeated» и не делать из bool более широких выводов о корректности программы.

PHP 8 · Reflection

public function ReflectionAttribute::isRepeated(): bool

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Ответить на узкий вопрос «is repeated» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionAttribute::isRepeatedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$method = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$r = $method->getAttributes(Demo\ReflectionLab\Label::class)[0];
$value = $r->isRepeated();
echo 'isRepeated: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isRepeated: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is repeated» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::__constructСоздать описание Class по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::__construct(object|string $objectOrClass): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание Class по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$objectOrClass
object|string
Объект либо полное имя уже доступного класса. Строка может задействовать автозагрузчик.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
echo 'класс: ', $r->getName(), "\n";
echo 'можно создать: ', $r->isInstantiable() ? 'да' : 'нет', "\n";
}
Ожидаемый результат
класс: Demo\ReflectionLab\CheckoutHandler
можно создать: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Class по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionClass::export(mixed $argument, bool $return = false): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionClass::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$text = (string) $r;
echo "export удалён\n";
echo 'замена содержит имя: ', str_contains($text, 'CheckoutHandler') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
export удалён
замена содержит имя: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getAttributesПолучить attributes из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionClass::getAttributes(?string $name = null, int $flags = 0): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить attributes из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
?string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода. Параметр необязательный; пропуск сохраняет поведение по умолчанию.
$flags
int
Битовые флаги только из перечисленных для данного метода констант. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getAttributesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getAttributes(Demo\ReflectionLab\Label::class);
echo 'getAttributes: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getAttributes: array(1): ReflectionAttribute:Demo\ReflectionLab\Label

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить attributes из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getConstantПолучить constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getConstant(string $name): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getConstantСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getConstant('VERSION');
echo 'getConstant: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getConstant: 1.0

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getConstantsПолучить constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getConstants(?int $filter = null): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$filter
?int
Битовая маска разрешённых модификаторов; null означает отсутствие фильтра. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getConstantsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getConstants(ReflectionClassConstant::IS_PUBLIC);
echo 'getConstants: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getConstants: array(3): BASE=base, OLD=old, VERSION=1.0

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getConstructorПолучить constructor из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getConstructor(): ?ReflectionMethod

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить constructor из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionMethod. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getConstructorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getConstructor();
echo 'getConstructor: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getConstructor: ReflectionMethod:CheckoutHandler::__construct

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить constructor из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getDefaultPropertiesПолучить default properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getDefaultProperties(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить default properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getDefaultPropertiesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getDefaultProperties();
echo 'status default: ', $value['status'], "\n";
echo 'public static calls: ', $value['calls'], "\n";
echo 'закрытых defaults не выводим: ', count($value) - 2, "\n";
}
Ожидаемый результат
status default: new
public static calls: 2
закрытых defaults не выводим: 2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить default properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getDocCommentПолучить doc comment из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getDocComment(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить doc comment из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getDocCommentСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getDocComment();
echo 'getDocComment: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDocComment: /** User-defined class inspected by the examples below. */

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить doc comment из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getEndLineПолучить end line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getEndLine(): int|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить end line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getEndLineСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getEndLine();
$value = is_int($value) && $value > 0 ? 'положительная строка' : $value;
echo 'getEndLine: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getEndLine: положительная строка

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить end line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getExtensionПолучить extension из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getExtension(): ?ReflectionExtension

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить extension из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionExtension. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getExtensionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getExtension();
echo 'getExtension: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtension: null

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getExtensionNameПолучить extension name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getExtensionName(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить extension name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getExtensionNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getExtensionName();
echo 'getExtensionName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtensionName: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getFileNameПолучить file name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getFileName(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить file name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getFileNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getFileName();
if (is_string($value)) $value = basename($value);
echo 'getFileName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getFileName: example.php

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить file name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getInterfaceNamesПолучить interface names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getInterfaceNames(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить interface names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getInterfaceNamesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getInterfaceNames();
echo 'getInterfaceNames: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getInterfaceNames: array(2): Demo\ReflectionLab\Payable, Stringable

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить interface names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getInterfacesПолучить interfaces из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getInterfaces(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить interfaces из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getInterfacesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getInterfaces();
echo 'getInterfaces: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getInterfaces: array(2): ReflectionClass:Demo\ReflectionLab\Payable, ReflectionClass:Stringable

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить interfaces из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getLazyInitializerПолучить lazy initializer из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionClass::getLazyInitializer(object $object): ?callable

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить lazy initializer из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Возвращаемый тип: ?callable. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getLazyInitializerСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
$initializer = $r->getLazyInitializer($object);
echo 'инициализатор: ', $initializer instanceof Closure ? 'Closure' : get_debug_type($initializer), "\n";
}
Ожидаемый результат
инициализатор: Closure

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить lazy initializer из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getMethodПолучить method из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getMethod(string $name): ReflectionMethod

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить method из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Возвращаемый тип: ReflectionMethod. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getMethodСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getMethod('handle');
echo 'getMethod: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getMethod: ReflectionMethod:CheckoutHandler::handle

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить method из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getMethodsПолучить methods из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getMethods(?int $filter = null): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить methods из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$filter
?int
Битовая маска разрешённых модификаторов; null означает отсутствие фильтра. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getMethodsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getMethods(ReflectionMethod::IS_PUBLIC);
echo 'getMethods: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getMethods: array(7): ReflectionMethod:CheckoutHandler::__construct, ReflectionMethod:CheckoutHandler::__destruct, ReflectionMethod:CheckoutHandler::__toString, ReflectionMethod:CheckoutHandler::handle, ReflectionMethod:CheckoutHandler::inherited, ReflectionMethod:CheckoutHandler::ping, ReflectionMethod:CheckoutHandler::writeLog

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить methods из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getModifiersПолучить modifiers из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getModifiers(): int

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить modifiers из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getModifiersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\FinalHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getModifiers();
$value = Reflection::getModifierNames($value);
echo 'getModifiers: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getModifiers: array(1): final

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить modifiers из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getNameПолучить name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: Demo\ReflectionLab\CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getNamespaceNameПолучить namespace name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getNamespaceName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить namespace name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getNamespaceNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getNamespaceName();
echo 'getNamespaceName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getNamespaceName: Demo\ReflectionLab

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить namespace name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getParentClassПолучить parent class из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getParentClass(): ReflectionClass|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить parent class из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionClass|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getParentClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getParentClass();
echo 'getParentClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getParentClass: ReflectionClass:Demo\ReflectionLab\BaseHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить parent class из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getPropertyПолучить property из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getProperty(string $name): ReflectionProperty

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить property из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Возвращаемый тип: ReflectionProperty. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getPropertyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getProperty('status');
echo 'getProperty: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getProperty: ReflectionProperty:CheckoutHandler::$status

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить property из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getReflectionConstantПолучить reflection constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClass::getReflectionConstant(string $name): ReflectionClassConstant|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить reflection constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Возвращаемый тип: ReflectionClassConstant|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getReflectionConstantСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getReflectionConstant('VERSION');
echo 'getReflectionConstant: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getReflectionConstant: ReflectionClassConstant:CheckoutHandler::VERSION

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить reflection constant из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getReflectionConstantsПолучить reflection constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClass::getReflectionConstants(?int $filter = null): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить reflection constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$filter
?int
Битовая маска разрешённых модификаторов; null означает отсутствие фильтра. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getReflectionConstantsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getReflectionConstants(ReflectionClassConstant::IS_PUBLIC);
echo 'getReflectionConstants: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getReflectionConstants: array(3): ReflectionClassConstant:BaseHandler::BASE, ReflectionClassConstant:CheckoutHandler::OLD, ReflectionClassConstant:CheckoutHandler::VERSION

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить reflection constants из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getShortNameПолучить short name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getShortName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить short name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getShortNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getShortName();
echo 'getShortName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getShortName: CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить short name из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getStartLineПолучить start line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getStartLine(): int|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить start line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getStartLineСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getStartLine();
$value = is_int($value) && $value > 0 ? 'положительная строка' : $value;
echo 'getStartLine: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getStartLine: положительная строка

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить start line из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getStaticPropertiesПолучить static properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getStaticProperties(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить static properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getStaticPropertiesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getStaticProperties();
echo 'getStaticProperties: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getStaticProperties: array(1): calls=2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить static properties из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getStaticPropertyValueПолучить static property value из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getStaticPropertyValue(string $name, mixed $default = …): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить static property value из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.
$default
mixed
Значение по официальному контракту; перед вызовом проверьте тип, происхождение и допустимость для исследуемого элемента. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getStaticPropertyValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getStaticPropertyValue('calls');
echo 'getStaticPropertyValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getStaticPropertyValue: 2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить static property value из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getTraitAliasesПолучить trait aliases из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getTraitAliases(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить trait aliases из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getTraitAliasesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getTraitAliases();
echo 'getTraitAliases: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTraitAliases: array(1): audit=Demo\ReflectionLab\WritesLog::writeLog

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить trait aliases из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getTraitNamesПолучить trait names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getTraitNames(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить trait names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getTraitNamesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getTraitNames();
echo 'getTraitNames: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTraitNames: array(1): Demo\ReflectionLab\WritesLog

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить trait names из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::getTraitsПолучить traits из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::getTraits(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить traits из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::getTraitsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getTraits();
echo 'getTraits: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTraits: array(1): ReflectionClass:Demo\ReflectionLab\WritesLog

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить traits из уже выбранного ReflectionClass и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::hasConstantПроверить наличие constant до чтения или вызова и обработать отрицательный результат отдельно.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionClass::hasConstant(string $name): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие constant до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::hasConstantСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->hasConstant('VERSION');
echo 'hasConstant: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasConstant: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие constant до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::hasMethodПроверить наличие method до чтения или вызова и обработать отрицательный результат отдельно.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionClass::hasMethod(string $name): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие method до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::hasMethodСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->hasMethod('handle');
echo 'hasMethod: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasMethod: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие method до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::hasPropertyПроверить наличие property до чтения или вызова и обработать отрицательный результат отдельно.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionClass::hasProperty(string $name): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие property до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::hasPropertyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->hasProperty('status');
echo 'hasProperty: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasProperty: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие property до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::implementsInterfaceПрименить ReflectionClass::implementsInterface к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::implementsInterface(ReflectionClass|string $interface): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Применить ReflectionClass::implementsInterface к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
$interface
ReflectionClass|string
Имя интерфейса или ReflectionClass интерфейса, с которым проверяется договор.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::implementsInterfaceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->implementsInterface(Demo\ReflectionLab\Payable::class);
echo 'implementsInterface: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
implementsInterface: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionClass::implementsInterface к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::initializeLazyObjectПрименить ReflectionClass::initializeLazyObject к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 8.4.0 · Reflection

public function ReflectionClass::initializeLazyObject(object $object): object

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Применить ReflectionClass::initializeLazyObject к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::initializeLazyObjectСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
$same = $r->initializeLazyObject($object);
echo 'тот же объект: ', $same === $object ? 'да' : 'нет', "\n";
echo 'итог: ', $object->total, "\n";
}
Ожидаемый результат
тот же объект: да
итог: 4500

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionClass::initializeLazyObject к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::inNamespaceПрименить ReflectionClass::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::inNamespace(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Применить ReflectionClass::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::inNamespaceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->inNamespace();
echo 'inNamespace: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
inNamespace: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionClass::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isAbstractОтветить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isAbstract(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isAbstractСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\AbstractHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isAbstract();
echo 'isAbstract: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isAbstract: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isAnonymousОтветить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.

PHP 7, PHP 8 · Reflection

public function ReflectionClass::isAnonymous(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isAnonymousСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass((new class {}));
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isAnonymous();
echo 'isAnonymous: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isAnonymous: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isCloneableОтветить на узкий вопрос «is cloneable» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isCloneable(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is cloneable» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isCloneableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isCloneable();
echo 'isCloneable: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isCloneable: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is cloneable» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isEnumОтветить на узкий вопрос «is enum» и не делать из bool более широких выводов о корректности программы.

PHP 8.1.0 · Reflection

public function ReflectionClass::isEnum(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is enum» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isEnumСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\PaymentStatus::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isEnum();
echo 'isEnum: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isEnum: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is enum» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isFinalОтветить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isFinal(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isFinalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\FinalHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isFinal();
echo 'isFinal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isFinal: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isInstanceОтветить на узкий вопрос «is instance» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isInstance(object $object): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is instance» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isInstanceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isInstance($object);
echo 'isInstance: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isInstance: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is instance» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isInstantiableОтветить на узкий вопрос «is instantiable» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isInstantiable(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is instantiable» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isInstantiableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isInstantiable();
echo 'isInstantiable: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isInstantiable: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is instantiable» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isInterfaceОтветить на узкий вопрос «is interface» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isInterface(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is interface» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isInterfaceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\Payable::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isInterface();
echo 'isInterface: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isInterface: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is interface» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isInternalОтветить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isInternal(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isInternalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(DateTimeImmutable::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isInternal();
echo 'isInternal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isInternal: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isIterableОтветить на узкий вопрос «is iterable» и не делать из bool более широких выводов о корректности программы.

PHP 7.2.0, PHP 8 · Reflection

public function ReflectionClass::isIterable(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is iterable» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isIterableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\IterableRows::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isIterable();
echo 'isIterable: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isIterable: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is iterable» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isIterateableОтветить на узкий вопрос «is iterateable» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isIterateable(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is iterateable» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isIterateableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\IterableRows::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isIterateable();
echo 'isIterateable: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isIterateable: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is iterateable» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isReadOnlyОтветить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.

PHP 8.2.0 · Reflection

public function ReflectionClass::isReadOnly(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isReadOnlyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\ReadonlyRecord::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isReadOnly();
echo 'isReadOnly: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isReadOnly: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isSubclassOfОтветить на узкий вопрос «is subclass of» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isSubclassOf(ReflectionClass|string $class): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is subclass of» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
$class
ReflectionClass|string
Имя класса или его ReflectionClass; не принимайте произвольное имя прямо из HTTP-запроса.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isSubclassOfСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isSubclassOf(Demo\ReflectionLab\BaseHandler::class);
echo 'isSubclassOf: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isSubclassOf: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is subclass of» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isTraitОтветить на узкий вопрос «is trait» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isTrait(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is trait» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isTraitСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\WritesLog::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isTrait();
echo 'isTrait: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isTrait: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is trait» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isUninitializedLazyObjectОтветить на узкий вопрос «is uninitialized lazy object» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionClass::isUninitializedLazyObject(object $object): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is uninitialized lazy object» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isUninitializedLazyObjectСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
echo $r->isUninitializedLazyObject($object) ? "до: да\n" : "до: нет\n";
$value = $object->total;
echo $r->isUninitializedLazyObject($object) ? "после: да\n" : "после: нет\n";
}
Ожидаемый результат
до: да
после: нет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is uninitialized lazy object» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::isUserDefinedОтветить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::isUserDefined(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::isUserDefinedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isUserDefined();
echo 'isUserDefined: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isUserDefined: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::markLazyObjectAsInitializedПрименить ReflectionClass::markLazyObjectAsInitialized к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 8.4.0 · Reflection

public function ReflectionClass::markLazyObjectAsInitialized(object $object): object

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Применить ReflectionClass::markLazyObjectAsInitialized к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::markLazyObjectAsInitializedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
$same = $r->markLazyObjectAsInitialized($object);
echo 'тот же объект: ', $same === $object ? 'да' : 'нет', "\n";
echo 'ленивый: ', $r->isUninitializedLazyObject($object) ? 'да' : 'нет', "\n";
}
Ожидаемый результат
тот же объект: да
ленивый: нет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionClass::markLazyObjectAsInitialized к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::newInstanceСоздать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::newInstance(mixed ...$args): object

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

ПараметрЧто именно передать
$args
mixed
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::newInstanceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->newInstance(12);
echo 'newInstance: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
newInstance: object:Demo\ReflectionLab\CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::newInstanceArgsСоздать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

PHP 5 >= 5.1.3, PHP 7, PHP 8 · Reflection

public function ReflectionClass::newInstanceArgs(array $args = []): ?object

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

ПараметрЧто именно передать
$args
array
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Возвращаемый тип: ?object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::newInstanceArgsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->newInstanceArgs([12]);
echo 'newInstanceArgs: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
newInstanceArgs: object:Demo\ReflectionLab\CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::newInstanceWithoutConstructorСоздать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionClass::newInstanceWithoutConstructor(): object

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::newInstanceWithoutConstructorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$instance = $r->newInstanceWithoutConstructor();
echo 'тип: ', $instance::class, "\n";
$id = $r->getProperty('id');
echo 'id готов: ', $id->isInitialized($instance) ? 'да' : 'нет', "\n";
}
Ожидаемый результат
тип: Demo\ReflectionLab\CheckoutHandler
id готов: нет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::newLazyGhostСоздать объект, состояние которого заполнится только при первом наблюдении.

PHP 8.4.0 · Reflection

public function ReflectionClass::newLazyGhost(callable $initializer, int $options = 0): object

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать объект, состояние которого заполнится только при первом наблюдении.

ПараметрЧто именно передать
$initializer
callable
Callback инициализации lazy ghost; получает объект и заполняет его состояние.
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::newLazyGhostСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
echo 'до чтения: ', $r->isUninitializedLazyObject($object) ? 'ленивый' : 'готов', "\n";
echo 'итог: ', $object->total, "\n";
echo 'после чтения: ', $r->isUninitializedLazyObject($object) ? 'ленивый' : 'готов', "\n";
}
Ожидаемый результат
до чтения: ленивый
итог: 4500
после чтения: готов

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать объект, состояние которого заполнится только при первом наблюдении. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::newLazyProxyСоздать заместитель, который по требованию получит настоящий объект из фабрики.

PHP 8.4.0 · Reflection

public function ReflectionClass::newLazyProxy(callable $factory, int $options = 0): object

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать заместитель, который по требованию получит настоящий объект из фабрики.

ПараметрЧто именно передать
$factory
callable
Callback lazy proxy; должен вернуть настоящий экземпляр отражённого класса.
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Возвращаемый тип: object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::newLazyProxyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyGateway { public function label(): string { return 'real'; } }
$r = new ReflectionClass(LazyGateway::class);
$factory = static fn (): LazyGateway => new LazyGateway();

$proxy = $r->newLazyProxy($factory);
echo 'до вызова: ', $r->isUninitializedLazyObject($proxy) ? 'ленивый' : 'готов', "\n";
echo 'метка: ', $proxy->label(), "\n";

}
Ожидаемый результат
до вызова: готов
метка: real

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать заместитель, который по требованию получит настоящий объект из фабрики. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::resetAsLazyGhostОчистить совместимый объект и снова сделать его ленивым ghost-объектом.

PHP 8.4.0 · Reflection

public function ReflectionClass::resetAsLazyGhost(object $object, callable $initializer, int $options = 0): void

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Очистить совместимый объект и снова сделать его ленивым ghost-объектом.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$initializer
callable
Callback инициализации lazy ghost; получает объект и заполняет его состояние.
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::resetAsLazyGhostСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyOrder { public int $total; }
$r = new ReflectionClass(LazyOrder::class);
$object = $r->newLazyGhost(function (LazyOrder $order): void { $order->total = 4500; });
$object->total = 10;
$r->resetAsLazyGhost($object, function (LazyOrder $order): void { $order->total = 99; });
echo 'после reset ленивый: ', $r->isUninitializedLazyObject($object) ? 'да' : 'нет', "\n";
echo 'после чтения: ', $object->total, "\n";
}
Ожидаемый результат
после reset ленивый: да
после чтения: 99

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Очистить совместимый объект и снова сделать его ленивым ghost-объектом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::resetAsLazyProxyОчистить совместимый объект и снова связать его с ленивой фабрикой proxy.

PHP 8.4.0 · Reflection

public function ReflectionClass::resetAsLazyProxy(object $object, callable $factory, int $options = 0): void

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Очистить совместимый объект и снова связать его с ленивой фабрикой proxy.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$factory
callable
Callback lazy proxy; должен вернуть настоящий экземпляр отражённого класса.
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::resetAsLazyProxyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyGateway { public function label(): string { return 'real'; } }
$r = new ReflectionClass(LazyGateway::class);
$factory = static fn (): LazyGateway => new LazyGateway();

$proxy = new LazyGateway();
$r->resetAsLazyProxy($proxy, $factory);
echo 'после reset: ', $r->isUninitializedLazyObject($proxy) ? 'ленивый' : 'готов', "\n";
echo 'метка: ', $proxy->label(), "\n";

}
Ожидаемый результат
после reset: готов
метка: real

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Очистить совместимый объект и снова связать его с ленивой фабрикой proxy. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::setStaticPropertyValueИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionClass::setStaticPropertyValue(string $name, mixed $value): void

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.
$value
mixed
Новое значение, которое всё равно проходит обычную проверку типа и readonly-ограничений.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::setStaticPropertyValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$r->setStaticPropertyValue('calls', 9);
echo 'calls: ', Demo\ReflectionLab\CheckoutHandler::$calls, "\n";
}
Ожидаемый результат
calls: 9

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClass::__toStringПолучить встроенное текстовое диагностическое представление ReflectionClass; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionClass::__toString(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить встроенное текстовое диагностическое представление ReflectionClass; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClass::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClass(Demo\ReflectionLab\CheckoutHandler::class);
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$text = (string) $r;
echo 'содержит имя: ', str_contains($text, 'CheckoutHandler') ? 'да' : 'нет', "\n";
echo 'строк: ', substr_count($text, "\n") + 1, "\n";
}
Ожидаемый результат
содержит имя: да
строк: 110

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionClass; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::__constructСоздать описание ClassConstant по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::__construct(object|string $class, string $constant): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Создать описание ClassConstant по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$class
object|string
Имя класса или его ReflectionClass; не принимайте произвольное имя прямо из HTTP-запроса.
$constant
string
Имя константы класса без значения и без имени класса.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
echo 'константа: ', $r->getDeclaringClass()->getShortName(), '::', $r->getName(), "\n";
}
Ожидаемый результат
константа: CheckoutHandler::VERSION

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание ClassConstant по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 7.1.0 · Reflection

public static function ReflectionClassConstant::export(mixed $class, string $name, bool $return = false): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionClassConstant::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
echo "export удалён\n";
echo 'замена: ', $r->getDeclaringClass()->getShortName(), '::', $r->getName(), '=', $r->getValue(), "\n";
}
Ожидаемый результат
export удалён
замена: CheckoutHandler::VERSION=1.0

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getAttributesПолучить attributes из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionClassConstant::getAttributes(?string $name = null, int $flags = 0): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить attributes из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
?string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода. Параметр необязательный; пропуск сохраняет поведение по умолчанию.
$flags
int
Битовые флаги только из перечисленных для данного метода констант. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getAttributesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getAttributes(Demo\ReflectionLab\Label::class);
echo 'getAttributes: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getAttributes: array(1): ReflectionAttribute:Demo\ReflectionLab\Label

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить attributes из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getDeclaringClassПолучить declaring class из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::getDeclaringClass(): ReflectionClass

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить declaring class из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getDeclaringClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getDeclaringClass();
echo 'getDeclaringClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDeclaringClass: ReflectionClass:Demo\ReflectionLab\CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить declaring class из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getDocCommentПолучить doc comment из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::getDocComment(): string|false

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить doc comment из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getDocCommentСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getDocComment();
echo 'getDocComment: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDocComment: /** Version used in a plugin compatibility check. */

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить doc comment из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getModifiersПолучить modifiers из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::getModifiers(): int

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить modifiers из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getModifiersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getModifiers();
$value = Reflection::getModifierNames($value);
echo 'getModifiers: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getModifiers: array(2): final, public

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить modifiers из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getNameПолучить name из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::getName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить name из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: VERSION

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getTypeПолучить type из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.3.0 · Reflection

public function ReflectionClassConstant::getType(): ?ReflectionType

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить type из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getType();
echo 'getType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getType: ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить type из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::getValueПолучить value из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::getValue(): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить value из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::getValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->getValue();
echo 'getValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getValue: 1.0

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить value из уже выбранного ReflectionClassConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::hasTypeПроверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.3.0 · Reflection

public function ReflectionClassConstant::hasType(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::hasTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->hasType();
echo 'hasType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasType: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isDeprecatedОтветить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionClassConstant::isDeprecated(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isDeprecatedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'OLD');
$value = $r->isDeprecated();
echo 'isDeprecated: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDeprecated: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isEnumCaseОтветить на узкий вопрос «is enum case» и не делать из bool более широких выводов о корректности программы.

PHP 8.1.0 · Reflection

public function ReflectionClassConstant::isEnumCase(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is enum case» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isEnumCaseСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
$value = $r->isEnumCase();
echo 'isEnumCase: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isEnumCase: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is enum case» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isFinalОтветить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

PHP 8.1.0 · Reflection

public function ReflectionClassConstant::isFinal(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isFinalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->isFinal();
echo 'isFinal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isFinal: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isPrivateОтветить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::isPrivate(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isPrivateСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'SECRET');
$value = $r->isPrivate();
echo 'isPrivate: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPrivate: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isProtectedОтветить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::isProtected(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isProtectedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'INTERNAL');
$value = $r->isProtected();
echo 'isProtected: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isProtected: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::isPublicОтветить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::isPublic(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::isPublicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$value = $r->isPublic();
echo 'isPublic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPublic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionClassConstant::__toStringПолучить встроенное текстовое диагностическое представление ReflectionClassConstant; формат не является стабильным API.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionClassConstant::__toString(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить встроенное текстовое диагностическое представление ReflectionClassConstant; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionClassConstant::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionClassConstant(Demo\ReflectionLab\CheckoutHandler::class, 'VERSION');
$text = (string) $r;
echo 'содержит VERSION: ', str_contains($text, 'VERSION') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит VERSION: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionClassConstant; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::__constructСоздать описание Constant по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8.4.0 · Reflection

public function ReflectionConstant::__construct(string $name): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Создать описание Constant по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
echo 'имя: ', $r->getName(), "\n";
}
Ожидаемый результат
имя: Demo\ReflectionLab\APP_LIMIT

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Constant по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getAttributesПолучить attributes из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Смотрите границу версии в официальной странице · Reflection

public function ReflectionConstant::getAttributes(?string $name = null, int $flags = 0): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить attributes из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
?string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода. Параметр необязательный; пропуск сохраняет поведение по умолчанию.
$flags
int
Битовые флаги только из перечисленных для данного метода констант. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getAttributesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\OLD_LIMIT');
$value = $r->getAttributes();
echo 'getAttributes: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getAttributes: array(1): ReflectionAttribute:Deprecated

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить attributes из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getExtensionПолучить extension из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.5.0 · Reflection

public function ReflectionConstant::getExtension(): ?ReflectionExtension

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить extension из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionExtension. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getExtensionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getExtension();
echo 'getExtension: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtension: null

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getExtensionNameПолучить extension name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.5.0 · Reflection

public function ReflectionConstant::getExtensionName(): string|false

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить extension name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getExtensionNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getExtensionName();
echo 'getExtensionName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtensionName: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getFileNameПолучить file name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.5.0 · Reflection

public function ReflectionConstant::getFileName(): string|false

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить file name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getFileNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getFileName();
if (is_string($value)) $value = basename($value);
echo 'getFileName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getFileName: example.php

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить file name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getNameПолучить name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionConstant::getName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: Demo\ReflectionLab\APP_LIMIT

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getNamespaceNameПолучить namespace name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionConstant::getNamespaceName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить namespace name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getNamespaceNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getNamespaceName();
echo 'getNamespaceName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getNamespaceName: Demo\ReflectionLab

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить namespace name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getShortNameПолучить short name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionConstant::getShortName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить short name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getShortNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getShortName();
echo 'getShortName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getShortName: APP_LIMIT

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить short name из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::getValueПолучить value из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionConstant::getValue(): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить value из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::getValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$value = $r->getValue();
echo 'getValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getValue: 25

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить value из уже выбранного ReflectionConstant и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::isDeprecatedОтветить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionConstant::isDeprecated(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::isDeprecatedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\OLD_LIMIT');
$value = $r->isDeprecated();
echo 'isDeprecated: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDeprecated: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionConstant::__toStringПолучить встроенное текстовое диагностическое представление ReflectionConstant; формат не является стабильным API.

PHP 8.4.0 · Reflection

public function ReflectionConstant::__toString(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить встроенное текстовое диагностическое представление ReflectionConstant; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionConstant::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    const APP_LIMIT = 25;
    #[\Deprecated('use APP_LIMIT')]
    const OLD_LIMIT = 24;
}
namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionConstant('Demo\ReflectionLab\APP_LIMIT');
$text = (string) $r;
echo 'содержит APP_LIMIT: ', str_contains($text, 'APP_LIMIT') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит APP_LIMIT: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionConstant; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::__constructСоздать описание Enum по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8.1.0 · Reflection

public function ReflectionEnum::__construct(object|string $objectOrClass): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание Enum по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$objectOrClass
object|string
Объект либо полное имя уже доступного класса. Строка может задействовать автозагрузчик.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
echo 'описание: ', reflectionLabValue($r), "\n";
}
Ожидаемый результат
описание: ReflectionEnum:Demo\ReflectionLab\PaymentStatus

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Enum по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::getBackingTypeПолучить backing type из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnum::getBackingType(): ?ReflectionNamedType

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить backing type из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionNamedType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::getBackingTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
$value = $r->getBackingType();
echo 'getBackingType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getBackingType: ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить backing type из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::getCaseПолучить case из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnum::getCase(string $name): ReflectionEnumUnitCase

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить case из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Возвращаемый тип: ReflectionEnumUnitCase. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::getCaseСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
$value = $r->getCase('Paid');
echo 'getCase: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getCase: ReflectionClassConstant:PaymentStatus::Paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить case из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::getCasesПолучить cases из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnum::getCases(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить cases из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::getCasesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
$value = $r->getCases();
echo 'getCases: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getCases: array(2): ReflectionClassConstant:PaymentStatus::New, ReflectionClassConstant:PaymentStatus::Paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить cases из уже выбранного ReflectionEnum и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::hasCaseПроверить наличие case до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.1.0 · Reflection

public function ReflectionEnum::hasCase(string $name): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие case до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::hasCaseСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
$value = $r->hasCase('Paid');
echo 'hasCase: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasCase: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие case до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnum::isBackedОтветить на узкий вопрос «is backed» и не делать из bool более широких выводов о корректности программы.

PHP 8.1.0 · Reflection

public function ReflectionEnum::isBacked(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is backed» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnum::isBackedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnum(Demo\ReflectionLab\PaymentStatus::class);
$value = $r->isBacked();
echo 'isBacked: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isBacked: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is backed» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnumBackedCase::__constructСоздать описание EnumBackedCase по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8.1.0 · Reflection

public function ReflectionEnumBackedCase::__construct(object|string $class, string $constant): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание EnumBackedCase по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$class
object|string
Имя класса или его ReflectionClass; не принимайте произвольное имя прямо из HTTP-запроса.
$constant
string
Имя константы класса без значения и без имени класса.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnumBackedCase::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnumBackedCase(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
echo 'описание: ', reflectionLabValue($r), "\n";
}
Ожидаемый результат
описание: ReflectionClassConstant:PaymentStatus::Paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание EnumBackedCase по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnumBackedCase::getBackingValueПолучить backing value из уже выбранного ReflectionEnumBackedCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnumBackedCase::getBackingValue(): string|int

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить backing value из уже выбранного ReflectionEnumBackedCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string|int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnumBackedCase::getBackingValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnumBackedCase(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
$value = $r->getBackingValue();
echo 'getBackingValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getBackingValue: paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить backing value из уже выбранного ReflectionEnumBackedCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnumUnitCase::__constructСоздать описание EnumUnitCase по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8.1.0 · Reflection

public function ReflectionEnumUnitCase::__construct(object|string $class, string $constant): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание EnumUnitCase по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$class
object|string
Имя класса или его ReflectionClass; не принимайте произвольное имя прямо из HTTP-запроса.
$constant
string
Имя константы класса без значения и без имени класса.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnumUnitCase::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnumUnitCase(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
echo 'описание: ', reflectionLabValue($r), "\n";
}
Ожидаемый результат
описание: ReflectionClassConstant:PaymentStatus::Paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание EnumUnitCase по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnumUnitCase::getEnumПолучить enum из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnumUnitCase::getEnum(): ReflectionEnum

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить enum из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionEnum. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnumUnitCase::getEnumСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnumUnitCase(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
$value = $r->getEnum();
echo 'getEnum: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getEnum: ReflectionEnum:Demo\ReflectionLab\PaymentStatus

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить enum из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionEnumUnitCase::getValueПолучить value из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionEnumUnitCase::getValue(): UnitEnum

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить value из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: UnitEnum. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionEnumUnitCase::getValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionEnumUnitCase(Demo\ReflectionLab\PaymentStatus::class, 'Paid');
$value = $r->getValue();
echo 'getValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getValue: Demo\ReflectionLab\PaymentStatus::Paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить value из уже выбранного ReflectionEnumUnitCase и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::__cloneПроверить правила клонирования объекта ReflectionExtension и не путать описание с копией исследуемого объекта.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::__clone(): void

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Проверить правила клонирования объекта ReflectionExtension и не путать описание с копией исследуемого объекта.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::__cloneСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
try { $copy = clone $r; echo "клонирование разрешено\n"; }
catch (Error $error) { echo "клонирование запрещено\n"; }
Ожидаемый результат
клонирование запрещено

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить правила клонирования объекта ReflectionExtension и не путать описание с копией исследуемого объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::__constructСоздать описание Extension по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::__construct(string $name): mixed

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Создать описание Extension по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::__constructСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
echo 'расширение: ', $r->getName(), "\n";
Ожидаемый результат
расширение: Reflection

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Extension по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionExtension::export(string $name, bool $return = false): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionExtension::exportСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
echo "export удалён\n";
echo 'замена: ', $r->getName(), "\n";
Ожидаемый результат
export удалён
замена: Reflection

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getClassesПолучить classes из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getClasses(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить classes из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getClassesСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getClasses();
echo 'getClasses: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getClasses: array(26): ReflectionClass:Reflection, ReflectionClass:ReflectionAttribute, ReflectionClass:ReflectionClass, ReflectionClass:ReflectionClassConstant, ReflectionClass:ReflectionConstant, ReflectionClass:ReflectionEnum, ReflectionClass:ReflectionEnumBackedCase, ReflectionClass:ReflectionEnumUnitCase

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить classes из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getClassNamesПолучить class names из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getClassNames(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить class names из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getClassNamesСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getClassNames();
echo 'getClassNames: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getClassNames: array(26): PropertyHookType, Reflection, ReflectionAttribute, ReflectionClass, ReflectionClassConstant, ReflectionConstant, ReflectionEnum, ReflectionEnumBackedCase

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить class names из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getConstantsПолучить constants из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getConstants(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить constants из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getConstantsСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getConstants();
echo 'getConstants: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getConstants: array(0): 

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить constants из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getDependenciesПолучить dependencies из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.3, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getDependencies(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить dependencies из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getDependenciesСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getDependencies();
echo 'getDependencies: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getDependencies: array(0): 

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить dependencies из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getFunctionsПолучить functions из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getFunctions(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить functions из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getFunctionsСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getFunctions();
echo 'getFunctions: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getFunctions: array(0): 

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить functions из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getINIEntriesПолучить i n i entries из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getINIEntries(): array

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить i n i entries из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getINIEntriesСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getINIEntries();
echo 'getINIEntries: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getINIEntries: array(0): 

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить i n i entries из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getNameПолучить name из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getName(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить name из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getNameСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getName: Reflection

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::getVersionПолучить version из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::getVersion(): ?string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить version из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::getVersionСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->getVersion();
echo 'getVersion: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getVersion: 8.5.11

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить version из уже выбранного ReflectionExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::infoВывести диагностическую информацию расширения; этот метод пишет вывод, а не возвращает массив.

PHP 5 >= 5.2.4, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::info(): void

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Вывести диагностическую информацию расширения; этот метод пишет вывод, а не возвращает массив.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::infoСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
ob_start();
$r->info();
$text = (string) ob_get_clean();
echo 'вывод содержит Reflection: ', str_contains($text, 'Reflection') ? 'да' : 'нет', "\n";
Ожидаемый результат
вывод содержит Reflection: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Вывести диагностическую информацию расширения; этот метод пишет вывод, а не возвращает массив. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::isPersistentОтветить на узкий вопрос «is persistent» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::isPersistent(): bool

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Ответить на узкий вопрос «is persistent» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::isPersistentСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->isPersistent();
echo 'isPersistent: ', reflectionLabValue($value), "\n";
Ожидаемый результат
isPersistent: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is persistent» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::isTemporaryОтветить на узкий вопрос «is temporary» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::isTemporary(): bool

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Ответить на узкий вопрос «is temporary» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::isTemporaryСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$value = $r->isTemporary();
echo 'isTemporary: ', reflectionLabValue($value), "\n";
Ожидаемый результат
isTemporary: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is temporary» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionExtension::__toStringПолучить встроенное текстовое диагностическое представление ReflectionExtension; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionExtension::__toString(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить встроенное текстовое диагностическое представление ReflectionExtension; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionExtension::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionExtension('Reflection');
$text = (string) $r;
echo 'содержит Reflection: ', str_contains($text, 'Reflection') ? 'да' : 'нет', "\n";
Ожидаемый результат
содержит Reflection: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionExtension; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::__constructСоздать описание Fiber по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 8.1.0 · Reflection

public function ReflectionFiber::__construct(Fiber $fiber): mixed

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Создать описание Fiber по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$fiber
Fiber
Уже созданный Fiber; состояние определяет, какие сведения о выполнении доступны.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::__constructСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
echo 'состояние: ', $fiber->isSuspended() ? 'приостановлен' : 'другое', "\n";
Ожидаемый результат
состояние: приостановлен

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Fiber по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::getCallableПолучить callable из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFiber::getCallable(): callable

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Получить callable из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: callable. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::getCallableСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
$value = $r->getCallable();
echo 'getCallable: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getCallable: Closure

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить callable из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::getExecutingFileПолучить executing file из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFiber::getExecutingFile(): ?string

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Получить executing file из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::getExecutingFileСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
$value = basename((string) $r->getExecutingFile());
echo 'файл: ', $value, "\n";
Ожидаемый результат
файл: example.php

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить executing file из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::getExecutingLineПолучить executing line из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFiber::getExecutingLine(): ?int

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Получить executing line из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::getExecutingLineСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
$value = $r->getExecutingLine();
echo 'строка положительная: ', is_int($value) && $value > 0 ? 'да' : 'нет', "\n";
Ожидаемый результат
строка положительная: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить executing line из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::getFiberПолучить fiber из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFiber::getFiber(): Fiber

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Получить fiber из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: Fiber. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::getFiberСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
$value = $r->getFiber();
echo 'getFiber: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getFiber: Fiber

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить fiber из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFiber::getTraceПолучить trace из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFiber::getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array

Зачем открывать эту карточку. Отладчик наблюдает приостановленный Fiber и показывает место ожидания, не возобновляя задачу.

Получить trace из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFiber::getTraceСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$fiber = new Fiber(function (): void {
    Fiber::suspend('waiting');
});
$fiber->start();
$r = new ReflectionFiber($fiber);
$value = $r->getTrace();
echo 'кадров: ', count($value), "\n";
Ожидаемый результат
кадров: 2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить trace из уже выбранного ReflectionFiber и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::__constructСоздать описание Function по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::__construct(Closure|string $function): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание Function по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$function
Closure|string
Имя функции, Closure или пара [класс/объект, метод] — в зависимости от конструктора.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
echo 'функция: ', $r->getName(), "\n";
}
Ожидаемый результат
функция: Demo\ReflectionLab\quote

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Function по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionFunction::export(string $name, bool $return = false): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionFunction::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
echo "export удалён\n";
echo 'замена: ', $r->getName(), "\n";
}
Ожидаемый результат
export удалён
замена: Demo\ReflectionLab\quote

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::getClosureПолучить closure из уже выбранного ReflectionFunction и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::getClosure(): Closure

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure из уже выбранного ReflectionFunction и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: Closure. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::getClosureСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getClosure();
echo 'getClosure: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getClosure: Closure

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure из уже выбранного ReflectionFunction и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::invokeДействительно вызвать отражённую функцию с позиционными аргументами.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::invoke(mixed ...$args): mixed

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Действительно вызвать отражённую функцию с позиционными аргументами.

ПараметрЧто именно передать
$args
mixed
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection. Исследуемая функция действительно выполняется и может иметь любые её обычные побочные эффекты.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::invokeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->invoke('SKU-7', 3, 'sale');
echo 'возврат: ', $value, "\n";
}
Ожидаемый результат
возврат: SKU-7:3:1:call1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Действительно вызвать отражённую функцию с позиционными аргументами. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::invokeArgsДействительно вызвать отражённую функцию, передав аргументы массивом.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::invokeArgs(array $args): mixed

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Действительно вызвать отражённую функцию, передав аргументы массивом.

ПараметрЧто именно передать
$args
array
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection. Исследуемая функция действительно выполняется и может иметь любые её обычные побочные эффекты.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::invokeArgsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->invokeArgs(['SKU-7', 3, 'sale']);
echo 'возврат: ', $value, "\n";
}
Ожидаемый результат
возврат: SKU-7:3:1:call1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Действительно вызвать отражённую функцию, передав аргументы массивом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::isAnonymousОтветить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.

PHP 8.2.0 · Reflection

public function ReflectionFunction::isAnonymous(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::isAnonymousСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction(static fn (): int => 1);
$value = $r->isAnonymous();
echo 'isAnonymous: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isAnonymous: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is anonymous» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::isDisabledОтветить на узкий вопрос «is disabled» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::isDisabled(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is disabled» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::isDisabledСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$value = $r->isDisabled();
restore_error_handler();
echo 'isDisabled: ', $value ? 'true' : 'false', "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
}
Ожидаемый результат
isDisabled: false
метод устарел: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is disabled» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunction::__toStringПолучить встроенное текстовое диагностическое представление ReflectionFunction; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionFunction::__toString(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить встроенное текстовое диагностическое представление ReflectionFunction; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunction::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$text = (string) $r;
echo 'содержит quote: ', str_contains($text, 'quote') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит quote: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionFunction; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::__cloneПроверить правила клонирования объекта ReflectionFunctionAbstract и не путать описание с копией исследуемого объекта.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::__clone(): void

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить правила клонирования объекта ReflectionFunctionAbstract и не путать описание с копией исследуемого объекта.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::__cloneСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
try { $copy = clone $r; echo "клонирование разрешено\n"; }
catch (Error $error) { echo "клонирование запрещено\n"; }
}
Ожидаемый результат
клонирование запрещено

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить правила клонирования объекта ReflectionFunctionAbstract и не путать описание с копией исследуемого объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getClosureCalledClassПолучить closure called class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.0.23, PHP 8.1.11 · Reflection

public function ReflectionFunctionAbstract::getClosureCalledClass(): ?ReflectionClass

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure called class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getClosureCalledClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction((new Demo\ReflectionLab\BoundService())->closure());
$value = $r->getClosureCalledClass();
echo 'getClosureCalledClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getClosureCalledClass: ReflectionClass:Demo\ReflectionLab\BoundService

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure called class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getClosureScopeClassПолучить closure scope class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getClosureScopeClass(): ?ReflectionClass

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure scope class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getClosureScopeClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction((new Demo\ReflectionLab\BoundService())->closure());
$value = $r->getClosureScopeClass();
echo 'getClosureScopeClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getClosureScopeClass: ReflectionClass:Demo\ReflectionLab\BoundService

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure scope class из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getClosureThisПолучить closure this из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getClosureThis(): ?object

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure this из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getClosureThisСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction((new Demo\ReflectionLab\BoundService())->closure());
$value = $r->getClosureThis();
echo 'getClosureThis: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getClosureThis: object:Demo\ReflectionLab\BoundService

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure this из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getClosureUsedVariablesПолучить closure used variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFunctionAbstract::getClosureUsedVariables(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure used variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getClosureUsedVariablesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction((new Demo\ReflectionLab\BoundService())->closure());
$value = $r->getClosureUsedVariables();
echo 'getClosureUsedVariables: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getClosureUsedVariables: array(1): prefix=bound

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure used variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getDocCommentПолучить doc comment из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getDocComment(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить doc comment из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getDocCommentСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getDocComment();
echo 'getDocComment: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDocComment: /** Build a deterministic quote line for the Reflection lab. */

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить doc comment из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getEndLineПолучить end line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getEndLine(): int|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить end line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getEndLineСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getEndLine();
echo 'строка положительная: ', is_int($value) && $value > 0 ? 'да' : 'нет', "\n";
}
Ожидаемый результат
строка положительная: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить end line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getExtensionПолучить extension из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getExtension(): ?ReflectionExtension

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить extension из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionExtension. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getExtensionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('strlen');
$value = $r->getExtension();
echo 'getExtension: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtension: ReflectionExtension:Core

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getExtensionNameПолучить extension name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getExtensionName(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить extension name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getExtensionNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('strlen');
$value = $r->getExtensionName();
echo 'getExtensionName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExtensionName: Core

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить extension name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getFileNameПолучить file name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getFileName(): string|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить file name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getFileNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getFileName();
echo 'файл: ', is_string($value) ? basename($value) : 'false', "\n";
}
Ожидаемый результат
файл: example.php

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить file name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getNameПолучить name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: Demo\ReflectionLab\quote

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getNamespaceNameПолучить namespace name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getNamespaceName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить namespace name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getNamespaceNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getNamespaceName();
echo 'getNamespaceName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getNamespaceName: Demo\ReflectionLab

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить namespace name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getNumberOfParametersПолучить number of parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getNumberOfParameters(): int

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить number of parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getNumberOfParametersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getNumberOfParameters();
echo 'getNumberOfParameters: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getNumberOfParameters: 3

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить number of parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getNumberOfRequiredParametersПолучить number of required parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getNumberOfRequiredParameters(): int

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить number of required parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getNumberOfRequiredParametersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getNumberOfRequiredParameters();
echo 'getNumberOfRequiredParameters: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getNumberOfRequiredParameters: 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить number of required parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getParametersПолучить parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getParameters(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getParametersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getParameters();
echo 'getParameters: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getParameters: array(3): ReflectionParameter:$quantity, ReflectionParameter:$sku, ReflectionParameter:$tags

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить parameters из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getReturnTypeПолучить return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getReturnType(): ?ReflectionType

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getReturnTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getReturnType();
echo 'getReturnType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getReturnType: ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getShortNameПолучить short name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getShortName(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить short name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getShortNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getShortName();
echo 'getShortName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getShortName: quote

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить short name из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getStartLineПолучить start line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getStartLine(): int|false

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить start line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int|false. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getStartLineСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getStartLine();
echo 'строка положительная: ', is_int($value) && $value > 0 ? 'да' : 'нет', "\n";
}
Ожидаемый результат
строка положительная: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить start line из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getStaticVariablesПолучить static variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::getStaticVariables(): array

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить static variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getStaticVariablesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->getStaticVariables();
echo 'getStaticVariables: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getStaticVariables: array(1): calls=0

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить static variables из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::getTentativeReturnTypeПолучить tentative return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionFunctionAbstract::getTentativeReturnType(): ?ReflectionType

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить tentative return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::getTentativeReturnTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(ArrayIterator::class, 'current');
$value = $r->getTentativeReturnType();
echo 'getTentativeReturnType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTentativeReturnType: ReflectionNamedType:mixed

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить tentative return type из уже выбранного ReflectionFunctionAbstract и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::hasReturnTypeПроверить наличие return type до чтения или вызова и обработать отрицательный результат отдельно.

PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::hasReturnType(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие return type до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::hasReturnTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->hasReturnType();
echo 'hasReturnType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasReturnType: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие return type до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::hasTentativeReturnTypeПроверить наличие tentative return type до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.1.0 · Reflection

public function ReflectionFunctionAbstract::hasTentativeReturnType(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие tentative return type до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::hasTentativeReturnTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(ArrayIterator::class, 'current');
$value = $r->hasTentativeReturnType();
echo 'hasTentativeReturnType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasTentativeReturnType: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие tentative return type до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::inNamespaceПрименить ReflectionFunctionAbstract::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::inNamespace(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Применить ReflectionFunctionAbstract::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::inNamespaceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->inNamespace();
echo 'inNamespace: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
inNamespace: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionFunctionAbstract::inNamespace к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isClosureОтветить на узкий вопрос «is closure» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isClosure(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is closure» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isClosureСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction(static fn (): int => 1);
$value = $r->isClosure();
echo 'isClosure: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isClosure: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is closure» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isDeprecatedОтветить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isDeprecated(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isDeprecatedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->isDeprecated();
echo 'isDeprecated: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDeprecated: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is deprecated» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isGeneratorОтветить на узкий вопрос «is generator» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.5.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isGenerator(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is generator» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isGeneratorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\rows');
$value = $r->isGenerator();
echo 'isGenerator: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isGenerator: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is generator» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isInternalОтветить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isInternal(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isInternalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('strlen');
$value = $r->isInternal();
echo 'isInternal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isInternal: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is internal» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isUserDefinedОтветить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isUserDefined(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isUserDefinedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->isUserDefined();
echo 'isUserDefined: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isUserDefined: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is user defined» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::isVariadicОтветить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.6.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::isVariadic(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::isVariadicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$value = $r->isVariadic();
echo 'isVariadic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isVariadic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::returnsReferenceОтветить на узкий вопрос «returns reference» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

public function ReflectionFunctionAbstract::returnsReference(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «returns reference» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionFunctionAbstract::returnsReferenceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\sharedCounter');
$value = $r->returnsReference();
echo 'returnsReference: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
returnsReference: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «returns reference» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionFunctionAbstract::__toStringПолучить встроенное текстовое диагностическое представление ReflectionFunctionAbstract; формат не является стабильным API.

PHP 5 >= 5.2.0, PHP 7, PHP 8 · Reflection

abstract public function ReflectionFunctionAbstract::__toString(): void

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить встроенное текстовое диагностическое представление ReflectionFunctionAbstract; формат не является стабильным API.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. Абстрактный договор реализуют конкретные ReflectionFunction и ReflectionMethod; прямого экземпляра ReflectionFunctionAbstract нет.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionFunctionAbstract::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionFunction('Demo\ReflectionLab\quote');
$text = (string) $r;
echo 'содержит quote: ', str_contains($text, 'quote') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит quote: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionFunctionAbstract; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::__constructСоздать описание Generator по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::__construct(Generator $generator): mixed

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Создать описание Generator по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$generator
Generator
Уже созданный объект Generator, обычно приостановленный на yield.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
echo 'текущее значение: ', $generator->current(), "\n";
}
Ожидаемый результат
текущее значение: first

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Generator по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getExecutingFileПолучить executing file из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getExecutingFile(): string

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить executing file из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getExecutingFileСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = basename($r->getExecutingFile());
echo 'файл: ', $value, "\n";
}
Ожидаемый результат
файл: example.php

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить executing file из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getExecutingGeneratorПолучить executing generator из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getExecutingGenerator(): Generator

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить executing generator из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: Generator. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getExecutingGeneratorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = $r->getExecutingGenerator();
echo 'getExecutingGenerator: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getExecutingGenerator: Generator

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить executing generator из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getExecutingLineПолучить executing line из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getExecutingLine(): int

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить executing line из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getExecutingLineСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = $r->getExecutingLine();
echo 'строка положительная: ', $value > 0 ? 'да' : 'нет', "\n";
}
Ожидаемый результат
строка положительная: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить executing line из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getFunctionПолучить function из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getFunction(): ReflectionFunctionAbstract

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить function из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionFunctionAbstract. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getFunctionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = $r->getFunction();
echo 'getFunction: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getFunction: ReflectionFunction:Demo\ReflectionLab\rows

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить function из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getThisПолучить this из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getThis(): ?object

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить this из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?object. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getThisСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = $r->getThis();
echo 'getThis: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getThis: null

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить this из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::getTraceПолучить trace из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionGenerator::getTrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT): array

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Получить trace из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$options
int
Комбинация только документированных флагов lazy object API. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::getTraceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
$value = $r->getTrace();
echo 'кадров: ', count($value), "\n";
}
Ожидаемый результат
кадров: 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить trace из уже выбранного ReflectionGenerator и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionGenerator::isClosedОтветить на узкий вопрос «is closed» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionGenerator::isClosed(): bool

Зачем открывать эту карточку. Отладчик выясняет, на каком yield остановился генератор и какая функция его создала.

Ответить на узкий вопрос «is closed» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionGenerator::isClosedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label { public function __construct(public string $value) {} }

    /** Build a deterministic quote line for the Reflection lab. */
    #[Label('function')]
    function quote(#[Label('sku')] string $sku, int $quantity = 2, string ...$tags): string
    {
        static $calls = 0;
        $calls++;
        return $sku . ':' . $quantity . ':' . count($tags) . ':call' . $calls;
    }

    function &sharedCounter(): int
    {
        static $counter = 4;
        return $counter;
    }

    function rows(): \Generator { yield 'first'; yield 'second'; }

    final class BoundService
    {
        public function closure(): \Closure
        {
            $prefix = 'bound';
            return function (string $value) use ($prefix): string {
                return $this::class . ':' . $prefix . ':' . $value;
            };
        }
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$generator = Demo\ReflectionLab\rows();
$generator->rewind();
$r = new ReflectionGenerator($generator);
echo 'до завершения: ', $r->isClosed() ? 'закрыт' : 'открыт', "\n";
$generator->next(); $generator->next();
echo 'после завершения: ', $r->isClosed() ? 'закрыт' : 'открыт', "\n";
}
Ожидаемый результат
до завершения: открыт
после завершения: закрыт

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is closed» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionIntersectionType::getTypesПолучить types из уже выбранного ReflectionIntersectionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.1.0 · Reflection

public function ReflectionIntersectionType::getTypes(): array

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить types из уже выбранного ReflectionIntersectionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionIntersectionType::getTypesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\intersection'))->getParameters()[0]->getType();
$value = $r->getTypes();
echo 'getTypes: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTypes: array(2): ReflectionNamedType:Demo\ReflectionLab\A, ReflectionNamedType:Demo\ReflectionLab\B

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить types из уже выбранного ReflectionIntersectionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::__constructСоздать описание Method по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::__construct(object|string $objectOrMethod, ?string $method = null): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание Method по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$objectOrMethod
object|string
Объект/класс и имя метода либо строка вида Class::method в поддерживаемой форме.
$method
?string
Имя метода либо строка Class::method для фабричного варианта. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
echo 'метод: ', $r->getDeclaringClass()->getShortName(), '::', $r->getName(), "\n";
}
Ожидаемый результат
метод: CheckoutHandler::handle

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Method по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::createFromMethodNameСоздать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

PHP 8.3.0 · Reflection

public static function ReflectionMethod::createFromMethodName(string $method): static

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика.

ПараметрЧто именно передать
$method
string
Имя метода либо строка Class::method для фабричного варианта.

Возврат. Возвращаемый тип: static. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::createFromMethodNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = ReflectionMethod::createFromMethodName('Demo\ReflectionLab\CheckoutHandler::handle');
echo 'метод: ', $r->getName(), "\n";
}
Ожидаемый результат
метод: handle

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать объект через метаданные только там, где инфраструктуре заранее разрешена такая фабрика. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionMethod::export(string $class, string $name, bool $return = false): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionMethod::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
echo "export удалён\n";
echo 'замена: ', $r->getDeclaringClass()->getShortName(), '::', $r->getName(), "\n";
}
Ожидаемый результат
export удалён
замена: CheckoutHandler::handle

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::getClosureПолучить closure из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::getClosure(?object $object = null): Closure

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить closure из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$object
?object
Конкретный объект подходящего класса; для static-элемента может не требоваться. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Возвращаемый тип: Closure. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, ValueError. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::getClosureСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$closure = $r->getClosure($object);
echo 'вызов Closure: ', $closure('SKU-1', 2), "\n";
}
Ожидаемый результат
вызов Closure: SKU-1:2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить closure из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::getDeclaringClassПолучить declaring class из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::getDeclaringClass(): ReflectionClass

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить declaring class из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::getDeclaringClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getDeclaringClass();
echo 'getDeclaringClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDeclaringClass: ReflectionClass:Demo\ReflectionLab\CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить declaring class из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::getModifiersПолучить modifiers из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::getModifiers(): int

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить modifiers из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::getModifiersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = Reflection::getModifierNames($r->getModifiers());
echo 'модификаторы: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
модификаторы: array(2): final, public

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить modifiers из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::getPrototypeПолучить prototype из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::getPrototype(): ReflectionMethod

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить prototype из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionMethod. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::getPrototypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'inherited');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->getPrototype();
echo 'getPrototype: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getPrototype: ReflectionMethod:BaseHandler::inherited

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить prototype из уже выбранного ReflectionMethod и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::hasPrototypeПроверить наличие prototype до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.2.0 · Reflection

public function ReflectionMethod::hasPrototype(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Проверить наличие prototype до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::hasPrototypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'inherited');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->hasPrototype();
echo 'hasPrototype: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasPrototype: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие prototype до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::invokeДействительно вызвать отражённый метод у выбранного объекта.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::invoke(?object $object, mixed ...$args): mixed

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Действительно вызвать отражённый метод у выбранного объекта.

ПараметрЧто именно передать
$object
?object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$args
mixed
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection. Исследуемая функция действительно выполняется и может иметь любые её обычные побочные эффекты.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::invokeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->invoke($object, 'SKU-1', 2);
echo 'возврат: ', $value, "\n";
}
Ожидаемый результат
возврат: SKU-1:2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Действительно вызвать отражённый метод у выбранного объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::invokeArgsДействительно вызвать отражённый метод, передав аргументы массивом.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::invokeArgs(?object $object, array $args): mixed

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Действительно вызвать отражённый метод, передав аргументы массивом.

ПараметрЧто именно передать
$object
?object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$args
array
Аргументы исследуемого вызова. invoke принимает их позиционно, invokeArgs — массивом.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection. Исследуемая функция действительно выполняется и может иметь любые её обычные побочные эффекты.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::invokeArgsСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->invokeArgs($object, ['SKU-1', 2]);
echo 'возврат: ', $value, "\n";
}
Ожидаемый результат
возврат: SKU-1:2

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Действительно вызвать отражённый метод, передав аргументы массивом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isAbstractОтветить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isAbstract(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isAbstractСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\AbstractHandler::class, 'run');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isAbstract();
echo 'isAbstract: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isAbstract: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isConstructorОтветить на узкий вопрос «is constructor» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isConstructor(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is constructor» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isConstructorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, '__construct');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isConstructor();
echo 'isConstructor: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isConstructor: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is constructor» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isDestructorОтветить на узкий вопрос «is destructor» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isDestructor(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is destructor» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isDestructorСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, '__destruct');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isDestructor();
echo 'isDestructor: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDestructor: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is destructor» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isFinalОтветить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isFinal(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isFinalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isFinal();
echo 'isFinal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isFinal: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isPrivateОтветить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isPrivate(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isPrivateСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'secretAction');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isPrivate();
echo 'isPrivate: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPrivate: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isProtectedОтветить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isProtected(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isProtectedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'protectedAction');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isProtected();
echo 'isProtected: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isProtected: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::isPublicОтветить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::isPublic(): bool

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::isPublicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$value = $r->isPublic();
echo 'isPublic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPublic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::setAccessibleИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 5 >= 5.3.2, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::setAccessible(bool $accessible): void

Зачем открывать эту карточку. Инфраструктура после allow-list и проверки контракта выполняет действие; сам Reflection не выдаёт разрешение.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$accessible
bool
Исторический переключатель доступности. В современных PHP private/protected уже доступны Reflection; метод фактически ничего не меняет.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::setAccessibleСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'secretAction');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$r->setAccessible(false);
restore_error_handler();
echo 'вызов private: ', $r->invoke($object), "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
echo "флаг в PHP 8.5 ничего не меняет\n";
}
Ожидаемый результат
вызов private: private-result
метод устарел: да
флаг в PHP 8.5 ничего не меняет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionMethod::__toStringПолучить встроенное текстовое диагностическое представление ReflectionMethod; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionMethod::__toString(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Получить встроенное текстовое диагностическое представление ReflectionMethod; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionMethod::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionMethod(Demo\ReflectionLab\CheckoutHandler::class, 'handle');
$object = new Demo\ReflectionLab\CheckoutHandler(7);
$text = (string) $r;
echo 'содержит handle: ', str_contains($text, 'handle') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит handle: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionMethod; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionNamedType::getNameПолучить name из уже выбранного ReflectionNamedType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.1.0, PHP 8 · Reflection

public function ReflectionNamedType::getName(): string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить name из уже выбранного ReflectionNamedType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionNamedType::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\named'))->getParameters()[0]->getType();
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionNamedType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionNamedType::isBuiltinОтветить на узкий вопрос «is builtin» и не делать из bool более широких выводов о корректности программы.

PHP 7, PHP 8 · Reflection

public function ReflectionNamedType::isBuiltin(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is builtin» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionNamedType::isBuiltinСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\named'))->getParameters()[0]->getType();
$value = $r->isBuiltin();
echo 'isBuiltin: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isBuiltin: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is builtin» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionObject::__constructСоздать описание Object по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionObject::__construct(object $object): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Создать описание Object по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionObject::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$object = new Demo\ReflectionLab\CheckoutHandler(7);
$r = new ReflectionObject($object);
echo 'объект класса: ', $r->getName(), "\n";
echo 'тот же instance: ', $r->isInstance($object) ? 'да' : 'нет', "\n";
}
Ожидаемый результат
объект класса: Demo\ReflectionLab\CheckoutHandler
тот же instance: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Object по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionObject::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionObject::export(object $argument, bool $return = false): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionObject::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_ALL | \Attribute::IS_REPEATABLE)]
    final class Label
    {
        public function __construct(public string $value) {}
    }

    interface Payable extends \Stringable {}

    trait WritesLog
    {
        public function writeLog(string $message): string { return 'log:' . $message; }
    }

    #[Label('base')]
    class BaseHandler
    {
        public const BASE = 'base';
        public function inherited(): string { return 'base'; }
    }

    /** User-defined class inspected by the examples below. */
    #[Label('checkout')]
    class CheckoutHandler extends BaseHandler implements Payable
    {
        use WritesLog { writeLog as protected audit; }

        /** Version used in a plugin compatibility check. */
        #[Label('version')]
        final public const string VERSION = '1.0';
        #[\Deprecated('use VERSION')]
        public const string OLD = 'old';
        protected const string INTERNAL = 'inside';
        private const string SECRET = 'hidden';

        public static int $calls = 2;
        /** Current business state. */
        #[Label('state')]
        public string $status = 'new';
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}

        public function inherited(): string { return 'child'; }

        #[Label('route')]
        #[Label('audit')]
        final public function handle(string $sku, int $quantity = 1): string
        {
            return $sku . ':' . $quantity;
        }

        public static function ping(): string { return 'pong'; }
        private function secretAction(): string { return 'private-result'; }
        protected function protectedAction(): string { return 'protected-result'; }
        public function __destruct() {}
        public function __toString(): string { return 'handler-' . $this->id; }
    }

    abstract class AbstractHandler { abstract public function run(): void; }
    final class FinalHandler {}
    readonly class ReadonlyRecord { public function __construct(public int $id) {} }
    class IterableRows implements \IteratorAggregate
    {
        public function getIterator(): \Traversable { yield 'row'; }
    }
    enum PaymentStatus: string { case New = 'new'; case Paid = 'paid'; }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$object = new Demo\ReflectionLab\CheckoutHandler(7);
$r = new ReflectionObject($object);
echo "ReflectionObject::export удалён\n";
echo 'замена: ', $r->getShortName(), "\n";
}
Ожидаемый результат
ReflectionObject::export удалён
замена: CheckoutHandler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::allowsNullОтветить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::allowsNull(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::allowsNullСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->allowsNull();
echo 'allowsNull: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
allowsNull: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::canBePassedByValueОтветить на узкий вопрос «can be passed by value» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::canBePassedByValue(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «can be passed by value» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::canBePassedByValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'attempts');
$value = $r->canBePassedByValue();
echo 'canBePassedByValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
canBePassedByValue: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «can be passed by value» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::__cloneПроверить правила клонирования объекта ReflectionParameter и не путать описание с копией исследуемого объекта.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::__clone(): void

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Проверить правила клонирования объекта ReflectionParameter и не путать описание с копией исследуемого объекта.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::__cloneСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
try { $copy = clone $r; echo "клонирование разрешено\n"; }
catch (Error $error) { echo "клонирование запрещено\n"; }
}
Ожидаемый результат
клонирование запрещено

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить правила клонирования объекта ReflectionParameter и не путать описание с копией исследуемого объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::__constructСоздать описание Parameter по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::__construct(mixed $function, string|int $param): mixed

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Создать описание Parameter по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$function
mixed
Имя функции, Closure или пара [класс/объект, метод] — в зависимости от конструктора.
$param
string|int
Имя или нулевая позиция параметра в сигнатуре.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
echo 'параметр: $', $r->getName(), '; позиция ', $r->getPosition(), "\n";
}
Ожидаемый результат
параметр: $host; позиция 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Parameter по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionParameter::export(string $function, string $parameter, bool $return = false): string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionParameter::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
echo "export удалён\n";
echo 'замена: $', $r->getName(), "\n";
}
Ожидаемый результат
export удалён
замена: $host

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getAttributesПолучить attributes из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionParameter::getAttributes(?string $name = null, int $flags = 0): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить attributes из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
?string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода. Параметр необязательный; пропуск сохраняет поведение по умолчанию.
$flags
int
Битовые флаги только из перечисленных для данного метода констант. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getAttributesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->getAttributes(Demo\ReflectionLab\Input::class);
echo 'атрибутов: ', count($value), "\n";
}
Ожидаемый результат
атрибутов: 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить attributes из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getClassПолучить class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getClass(): ?ReflectionClass

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'service');
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$value = $r->getClass();
restore_error_handler();
echo 'getClass: ', reflectionLabValue($value), "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
}
Ожидаемый результат
getClass: ReflectionClass:Demo\ReflectionLab\Service
метод устарел: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getDeclaringClassПолучить declaring class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getDeclaringClass(): ?ReflectionClass

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить declaring class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getDeclaringClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, '__construct'], 'id');
$value = $r->getDeclaringClass();
echo 'getDeclaringClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDeclaringClass: ReflectionClass:Demo\ReflectionLab\Handler

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить declaring class из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getDeclaringFunctionПолучить declaring function из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getDeclaringFunction(): ReflectionFunctionAbstract

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить declaring function из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionFunctionAbstract. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getDeclaringFunctionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->getDeclaringFunction();
echo 'getDeclaringFunction: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDeclaringFunction: ReflectionMethod:Handler::configure

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить declaring function из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getDefaultValueПолучить default value из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.0.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getDefaultValue(): mixed

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить default value из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getDefaultValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'options');
$value = $r->getDefaultValue();
echo 'getDefaultValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDefaultValue: array(0): 

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить default value из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getDefaultValueConstantNameПолучить default value constant name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.6, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getDefaultValueConstantName(): ?string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить default value constant name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getDefaultValueConstantNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'limit');
$value = $r->getDefaultValueConstantName();
echo 'getDefaultValueConstantName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDefaultValueConstantName: Demo\ReflectionLab\PHP_INT_MAX

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить default value constant name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getNameПолучить name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getName(): string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: host

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getPositionПолучить position из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getPosition(): int

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить position из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getPositionСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->getPosition();
echo 'getPosition: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getPosition: 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить position из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::getTypeПолучить type из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7, PHP 8 · Reflection

public function ReflectionParameter::getType(): ?ReflectionType

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить type из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::getTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->getType();
echo 'getType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getType: ReflectionNamedType:?string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить type из уже выбранного ReflectionParameter и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::hasTypeПроверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

PHP 7, PHP 8 · Reflection

public function ReflectionParameter::hasType(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::hasTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$value = $r->hasType();
echo 'hasType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasType: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isArrayОтветить на узкий вопрос «is array» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.1.2, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isArray(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is array» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isArrayСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'options');
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$value = $r->isArray();
restore_error_handler();
echo 'isArray: ', reflectionLabValue($value), "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
}
Ожидаемый результат
isArray: true
метод устарел: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is array» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isCallableОтветить на узкий вопрос «is callable» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isCallable(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is callable» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isCallableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'onReady');
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$value = $r->isCallable();
restore_error_handler();
echo 'isCallable: ', reflectionLabValue($value), "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
}
Ожидаемый результат
isCallable: true
метод устарел: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is callable» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isDefaultValueAvailableОтветить на узкий вопрос «is default value available» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.0.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isDefaultValueAvailable(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is default value available» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isDefaultValueAvailableСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'options');
$value = $r->isDefaultValueAvailable();
echo 'isDefaultValueAvailable: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDefaultValueAvailable: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is default value available» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isDefaultValueConstantОтветить на узкий вопрос «is default value constant» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.4.6, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isDefaultValueConstant(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is default value constant» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isDefaultValueConstantСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'limit');
$value = $r->isDefaultValueConstant();
echo 'isDefaultValueConstant: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDefaultValueConstant: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is default value constant» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isOptionalОтветить на узкий вопрос «is optional» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.0.3, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isOptional(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is optional» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isOptionalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'options');
$value = $r->isOptional();
echo 'isOptional: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isOptional: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is optional» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isPassedByReferenceОтветить на узкий вопрос «is passed by reference» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isPassedByReference(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is passed by reference» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isPassedByReferenceСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'attempts');
$value = $r->isPassedByReference();
echo 'isPassedByReference: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPassedByReference: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is passed by reference» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isPromotedОтветить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.

PHP 8 · Reflection

public function ReflectionParameter::isPromoted(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isPromotedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, '__construct'], 'id');
$value = $r->isPromoted();
echo 'isPromoted: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPromoted: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::isVariadicОтветить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.

PHP 5 >= 5.6.0, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::isVariadic(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::isVariadicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'tags');
$value = $r->isVariadic();
echo 'isVariadic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isVariadic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is variadic» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionParameter::__toStringПолучить встроенное текстовое диагностическое представление ReflectionParameter; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionParameter::__toString(): string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить встроенное текстовое диагностическое представление ReflectionParameter; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionParameter::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PARAMETER)]
    final class Input { public function __construct(public string $label) {} }
    final class Service {}
    final class Handler
    {
        public function __construct(public readonly int $id) {}
        public function configure(
            Service $service,
            #[Input('host')] ?string $host,
            array $options = [],
            ?callable $onReady = null,
            int &$attempts = 0,
            int $limit = PHP_INT_MAX,
            string ...$tags,
        ): void {}
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionParameter([Demo\ReflectionLab\Handler::class, 'configure'], 'host');
$text = (string) $r;
echo 'содержит $host: ', str_contains($text, '$host') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит $host: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionParameter; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::__cloneПроверить правила клонирования объекта ReflectionProperty и не путать описание с копией исследуемого объекта.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::__clone(): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить правила клонирования объекта ReflectionProperty и не путать описание с копией исследуемого объекта.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::__cloneСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
try { $copy = clone $r; echo "клонирование разрешено\n"; }
catch (Error $error) { echo "клонирование запрещено\n"; }
}
Ожидаемый результат
клонирование запрещено

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить правила клонирования объекта ReflectionProperty и не путать описание с копией исследуемого объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::__constructСоздать описание Property по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::__construct(object|string $class, string $property): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Создать описание Property по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$class
object|string
Имя класса или его ReflectionClass; не принимайте произвольное имя прямо из HTTP-запроса.
$property
string
Имя объявленного свойства.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::__constructСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
echo 'свойство: $', $r->getName(), "\n";
}
Ожидаемый результат
свойство: $status

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание Property по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5, PHP 7 · Reflection

public static function ReflectionProperty::export(mixed $class, string $name, bool $return = false): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionProperty::exportСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
echo "export удалён\n";
echo 'замена: $', $r->getName(), "\n";
}
Ожидаемый результат
export удалён
замена: $status

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getAttributesПолучить attributes из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionProperty::getAttributes(?string $name = null, int $flags = 0): array

Зачем открывать эту карточку. Роутер, валидатор или контейнер читает заранее разрешённые атрибуты возле класса, метода или параметра.

Получить attributes из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$name
?string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода. Параметр необязательный; пропуск сохраняет поведение по умолчанию.
$flags
int
Битовые флаги только из перечисленных для данного метода констант. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getAttributesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getAttributes(Demo\ReflectionLab\Field::class);
echo 'атрибутов: ', count($value), "\n";
}
Ожидаемый результат
атрибутов: 1

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить attributes из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getDeclaringClassПолучить declaring class из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::getDeclaringClass(): ReflectionClass

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить declaring class из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ReflectionClass. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getDeclaringClassСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getDeclaringClass();
echo 'getDeclaringClass: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDeclaringClass: ReflectionClass:Demo\ReflectionLab\Product

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить declaring class из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getDefaultValueПолучить default value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionProperty::getDefaultValue(): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить default value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getDefaultValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getDefaultValue();
echo 'getDefaultValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDefaultValue: new

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить default value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getDocCommentПолучить doc comment из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.1.0, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::getDocComment(): string|false

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить doc comment из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строка при наличии сведений, строго false, когда источник для этого объявления неприменим.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getDocCommentСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getDocComment();
echo 'getDocComment: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getDocComment: /** Public state used in a serializer. */

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить doc comment из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getHookПолучить hook из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionProperty::getHook(PropertyHookType $type): ?ReflectionMethod

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить hook из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$type
PropertyHookType
Конкретный PropertyHookType::Get или PropertyHookType::Set.

Возврат. Возвращаемый тип: ?ReflectionMethod. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getHookСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'title');
$value = $r->getHook(PropertyHookType::Get);
echo 'getHook: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getHook: ReflectionMethod:HookedProduct::$title::get

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить hook из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getHooksПолучить hooks из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionProperty::getHooks(): array

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить hooks из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getHooksСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'title');
$value = $r->getHooks();
echo 'getHooks: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getHooks: array(2): ReflectionMethod:HookedProduct::$title::get, ReflectionMethod:HookedProduct::$title::set

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить hooks из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getMangledNameПолучить mangled name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

Смотрите границу версии в официальной странице · Reflection

public function ReflectionProperty::getMangledName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить mangled name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getMangledNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getMangledName();
echo 'getMangledName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getMangledName: status

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить mangled name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getModifiersПолучить modifiers из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::getModifiers(): int

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить modifiers из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: int. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getModifiersСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = Reflection::getModifierNames($r->getModifiers());
echo 'модификаторы: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
модификаторы: array(1): public

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить modifiers из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getNameПолучить name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::getName(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getNameСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getName: status

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getRawValueПолучить raw value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionProperty::getRawValue(object $object): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить raw value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getRawValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getRawValue($product);
echo 'getRawValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getRawValue: new

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить raw value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getSettableTypeПолучить settable type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8.4.0 · Reflection

public function ReflectionProperty::getSettableType(): ?ReflectionType

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить settable type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getSettableTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'title');
$value = $r->getSettableType();
echo 'getSettableType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getSettableType: ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить settable type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getTypeПолучить type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 7.4.0, PHP 8 · Reflection

public function ReflectionProperty::getType(): ?ReflectionType

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: ?ReflectionType. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getType();
echo 'getType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getType: ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить type из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::getValueПолучить value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::getValue(?object $object = null): mixed

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
$object
?object
Конкретный объект подходящего класса; для static-элемента может не требоваться. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::getValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->getValue($product);
echo 'getValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getValue: new

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить value из уже выбранного ReflectionProperty и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::hasDefaultValueПроверить наличие default value до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8 · Reflection

public function ReflectionProperty::hasDefaultValue(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить наличие default value до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::hasDefaultValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->hasDefaultValue();
echo 'hasDefaultValue: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasDefaultValue: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие default value до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::hasHookПроверить наличие hook до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.4.0 · Reflection

public function ReflectionProperty::hasHook(PropertyHookType $type): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить наличие hook до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
$type
PropertyHookType
Конкретный PropertyHookType::Get или PropertyHookType::Set.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::hasHookСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'title');
$value = $r->hasHook(PropertyHookType::Get);
echo 'hasHook: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasHook: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие hook до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::hasHooksПроверить наличие hooks до чтения или вызова и обработать отрицательный результат отдельно.

PHP 8.4.0 · Reflection

public function ReflectionProperty::hasHooks(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить наличие hooks до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::hasHooksСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'title');
$value = $r->hasHooks();
echo 'hasHooks: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasHooks: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие hooks до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::hasTypeПроверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

PHP 7.4.0, PHP 8 · Reflection

public function ReflectionProperty::hasType(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::hasTypeСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->hasType();
echo 'hasType: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
hasType: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить наличие type до чтения или вызова и обработать отрицательный результат отдельно. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isAbstractОтветить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isAbstract(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isAbstractСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\AbstractView::class, 'title');
$value = $r->isAbstract();
echo 'isAbstract: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isAbstract: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is abstract» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isDefaultОтветить на узкий вопрос «is default» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::isDefault(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is default» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isDefaultСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->isDefault();
echo 'isDefault: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDefault: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is default» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isDynamicОтветить на узкий вопрос «is dynamic» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isDynamic(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is dynamic» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isDynamicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty($bag, 'runtime');
$value = $r->isDynamic();
echo 'isDynamic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isDynamic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is dynamic» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isFinalОтветить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isFinal(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isFinalСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->isFinal();
echo 'isFinal: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isFinal: false

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is final» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isLazyОтветить на узкий вопрос «is lazy» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isLazy(object $object): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is lazy» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isLazyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyProduct { public int $stock; }
$class = new ReflectionClass(LazyProduct::class);
$object = $class->newLazyGhost(function (LazyProduct $value): void { $value->stock = 8; });
$r = $class->getProperty('stock');
echo 'lazy property: ', $r->isLazy($object) ? 'да' : 'нет', "\n";
}
Ожидаемый результат
lazy property: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is lazy» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isPrivateОтветить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::isPrivate(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isPrivateСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'token');
$value = $r->isPrivate();
echo 'isPrivate: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPrivate: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is private» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isPrivateSetОтветить на узкий вопрос «is private set» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isPrivateSet(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is private set» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isPrivateSetСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\AccessModel::class, 'owner');
$value = $r->isPrivateSet();
echo 'isPrivateSet: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPrivateSet: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is private set» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isPromotedОтветить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.

PHP 8 · Reflection

public function ReflectionProperty::isPromoted(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isPromotedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'id');
$value = $r->isPromoted();
echo 'isPromoted: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPromoted: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is promoted» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isProtectedОтветить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::isProtected(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isProtectedСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'channel');
$value = $r->isProtected();
echo 'isProtected: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isProtected: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is protected» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isProtectedSetОтветить на узкий вопрос «is protected set» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isProtectedSet(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is protected set» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isProtectedSetСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\AccessModel::class, 'state');
$value = $r->isProtectedSet();
echo 'isProtectedSet: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isProtectedSet: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is protected set» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isPublicОтветить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::isPublic(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isPublicСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$value = $r->isPublic();
echo 'isPublic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isPublic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is public» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isReadOnlyОтветить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.

PHP 8.1.0 · Reflection

public function ReflectionProperty::isReadOnly(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isReadOnlyСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'id');
$value = $r->isReadOnly();
echo 'isReadOnly: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isReadOnly: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is read only» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isStaticОтветить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::isStatic(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isStaticСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'instances');
$value = $r->isStatic();
echo 'isStatic: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isStatic: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is static» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::isVirtualОтветить на узкий вопрос «is virtual» и не делать из bool более широких выводов о корректности программы.

PHP 8.4.0 · Reflection

public function ReflectionProperty::isVirtual(): bool

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Ответить на узкий вопрос «is virtual» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::isVirtualСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\HookedProduct::class, 'label');
$value = $r->isVirtual();
echo 'isVirtual: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
isVirtual: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «is virtual» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::setAccessibleИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 5 >= 5.3.0, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::setAccessible(bool $accessible): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$accessible
bool
Исторический переключатель доступности. В современных PHP private/protected уже доступны Reflection; метод фактически ничего не меняет.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::setAccessibleСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$deprecated = false;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level === E_DEPRECATED) { $deprecated = true; return true; }
    return false;
});
$r->setAccessible(false);
restore_error_handler();
echo 'значение: ', $r->getValue($product), "\n";
echo 'метод устарел: ', $deprecated ? 'да' : 'нет', "\n";
echo "флаг в PHP 8.5 ничего не меняет\n";
}
Ожидаемый результат
значение: new
метод устарел: да
флаг в PHP 8.5 ничего не меняет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::setRawValueИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 8.4.0 · Reflection

public function ReflectionProperty::setRawValue(object $object, mixed $value): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$value
mixed
Новое значение, которое всё равно проходит обычную проверку типа и readonly-ограничений.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::setRawValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$r->setRawValue($product, 'paid');
echo 'status: ', $product->status, "\n";
}
Ожидаемый результат
status: paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::setRawValueWithoutLazyInitializationИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 8.4.0 · Reflection

public function ReflectionProperty::setRawValueWithoutLazyInitialization(object $object, mixed $value): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.
$value
mixed
Новое значение, которое всё равно проходит обычную проверку типа и readonly-ограничений.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::setRawValueWithoutLazyInitializationСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyProduct { public int $stock; }
$class = new ReflectionClass(LazyProduct::class);
$object = $class->newLazyGhost(function (LazyProduct $value): void { $value->stock = 8; });
$r = $class->getProperty('stock');
$r->setRawValueWithoutLazyInitialization($object, 5);
echo 'объект ещё ленивый: ', $class->isUninitializedLazyObject($object) ? 'да' : 'нет', "\n";
echo 'stock: ', $r->getRawValue($object), "\n";
}
Ожидаемый результат
объект ещё ленивый: нет
stock: 5

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::setValueИзменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::setValue(mixed $objectOrValue, mixed $value = …): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий.

ПараметрЧто именно передать
$objectOrValue
mixed
Для instance-свойства — объект; для static-свойства однопараметрическая форма принимает новое значение.
$value
mixed
Новое значение, которое всё равно проходит обычную проверку типа и readonly-ограничений. Параметр необязательный; пропуск сохраняет поведение по умолчанию.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException, Error. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::setValueСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$r->setValue($product, 'paid');
echo 'status: ', $product->status, "\n";
}
Ожидаемый результат
status: paid

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Изменить выбранное значение через Reflection, сохраняя проверки типов и явно ограничивая технический сценарий. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::skipLazyInitializationПрименить ReflectionProperty::skipLazyInitialization к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

PHP 8.4.0 · Reflection

public function ReflectionProperty::skipLazyInitialization(object $object): void

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Применить ReflectionProperty::skipLazyInitialization к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат.

ПараметрЧто именно передать
$object
object
Конкретный объект подходящего класса; для static-элемента может не требоваться.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::skipLazyInitializationСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


class LazyProduct { public int $stock; }
$class = new ReflectionClass(LazyProduct::class);
$object = $class->newLazyGhost(function (LazyProduct $value): void { $value->stock = 8; });
$r = $class->getProperty('stock');
$r->skipLazyInitialization($object);
echo 'свойство lazy: ', $r->isLazy($object) ? 'да' : 'нет', "\n";
}
Ожидаемый результат
свойство lazy: нет

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Применить ReflectionProperty::skipLazyInitialization к конкретной диагностической или инфраструктурной задаче и увидеть фактический результат. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionProperty::__toStringПолучить встроенное текстовое диагностическое представление ReflectionProperty; формат не является стабильным API.

PHP 5, PHP 7, PHP 8 · Reflection

public function ReflectionProperty::__toString(): string

Зачем открывать эту карточку. Гидратор, сериализатор или диагностический инструмент проверяет объявление до безопасного чтения значения.

Получить встроенное текстовое диагностическое представление ReflectionProperty; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionProperty::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    #[\Attribute(\Attribute::TARGET_PROPERTY)]
    final class Field { public function __construct(public string $label) {} }

    #[\AllowDynamicProperties]
    class DynamicBag {}

    class Product
    {
        public static int $instances = 3;
        #[Field('state')]
        /** Public state used in a serializer. */
        public string $status = 'new';
        public int $stock;
        protected string $channel = 'web';
        private string $token = 'secret';

        public function __construct(public readonly int $id = 7) {}
    }

    class HookedProduct
    {
        private string $rawTitle = 'desk';
        public string $title {
            get => strtoupper($this->rawTitle);
            set { $this->rawTitle = trim($value); }
        }
        final public string $label { get => 'product:' . $this->rawTitle; }
    }

    abstract class AbstractView
    {
        abstract public string $title { get; }
    }

    class AccessModel
    {
        public private(set) string $owner = 'team';
        public protected(set) string $state = 'new';
    }
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}


$product = new Demo\ReflectionLab\Product(7);
$hooked = new Demo\ReflectionLab\HookedProduct();
$access = new Demo\ReflectionLab\AccessModel();
$bag = new Demo\ReflectionLab\DynamicBag();
$bag->runtime = 'created';

$r = new ReflectionProperty(Demo\ReflectionLab\Product::class, 'status');
$text = (string) $r;
echo 'содержит status: ', str_contains($text, 'status') ? 'да' : 'нет', "\n";
}
Ожидаемый результат
содержит status: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionProperty; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionReference::__constructПонять, почему ReflectionReference нельзя создать напрямую и где взять корректный экземпляр.

PHP 7.4.0, PHP 8 · Reflection

public function ReflectionReference::__construct(): mixed

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Понять, почему ReflectionReference нельзя создать напрямую и где взять корректный экземпляр.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionReference::__constructСамостоятельный пример
<?php
declare(strict_types=1);

try { $r = new ReflectionReference(); echo "создан\n"; }
catch (Error $error) { echo "напрямую создать нельзя\n"; }
$value = 5;
$array = ['shared' => &$value];
$r = ReflectionReference::fromArrayElement($array, 'shared');
echo 'фабрика вернула: ', $r::class, "\n";
Ожидаемый результат
напрямую создать нельзя
фабрика вернула: ReflectionReference

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Понять, почему ReflectionReference нельзя создать напрямую и где взять корректный экземпляр. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionType::allowsNullОтветить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.

PHP 7, PHP 8 · Reflection

public function ReflectionType::allowsNull(): bool

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Строго bool: true подтверждает только вопрос в названии метода, false — его отрицание.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionType::allowsNullСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\nullable'))->getParameters()[0]->getType();
$value = $r->allowsNull();
echo 'allowsNull: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
allowsNull: true

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Ответить на узкий вопрос «allows null» и не делать из bool более широких выводов о корректности программы. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionType::__toStringПолучить встроенное текстовое диагностическое представление ReflectionType; формат не является стабильным API.

PHP 7, PHP 8 · Reflection

public function ReflectionType::__toString(): string

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить встроенное текстовое диагностическое представление ReflectionType; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionType::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\nullable'))->getParameters()[0]->getType();
echo 'тип: ', (string) $r, "\n";
}
Ожидаемый результат
тип: ?string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionType; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionUnionType::getTypesПолучить types из уже выбранного ReflectionUnionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 8 · Reflection

public function ReflectionUnionType::getTypes(): array

Зачем открывать эту карточку. Контейнер или генератор документации читает контракт параметров до создания и вызова сервиса.

Получить types из уже выбранного ReflectionUnionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Массив значений или Reflection-описаний. Порядок не всегда является договором; сортируйте только для своего отчёта.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionUnionType::getTypesСамостоятельный пример
<?php
declare(strict_types=1);

namespace Demo\ReflectionLab {
    interface A {}
    interface B {}
    function named(string $value): void {}
    function nullable(?string $value): void {}
    function union(string|int $value): void {}
    function intersection(A&B $value): void {}
}

namespace {


function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = (new ReflectionFunction('Demo\ReflectionLab\union'))->getParameters()[0]->getType();
$value = $r->getTypes();
echo 'getTypes: ', reflectionLabValue($value), "\n";
}
Ожидаемый результат
getTypes: array(2): ReflectionNamedType:int, ReflectionNamedType:string

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить types из уже выбранного ReflectionUnionType и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::__cloneПроверить правила клонирования объекта ReflectionZendExtension и не путать описание с копией исследуемого объекта.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::__clone(): void

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Проверить правила клонирования объекта ReflectionZendExtension и не путать описание с копией исследуемого объекта.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Осмысленного возвращаемого значения нет; наблюдайте изменение выбранного объекта или вывод.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::__cloneСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
try { $copy = clone $r; echo "клонирование разрешено\n"; }
catch (Error $error) { echo "клонирование запрещено\n"; }
Ожидаемый результат
клонирование запрещено

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Проверить правила клонирования объекта ReflectionZendExtension и не путать описание с копией исследуемого объекта. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::__constructСоздать описание ZendExtension по конкретному имени или объекту и получить ошибку для неизвестной цели.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::__construct(string $name): mixed

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Создать описание ZendExtension по конкретному имени или объекту и получить ошибку для неизвестной цели.

ПараметрЧто именно передать
$name
string
Точное имя искомого элемента; регистр и область имён имеют значение согласно контракту конкретного метода.

Возврат. Тип зависит от исследуемого объявления. Не доверяйте значению только потому, что оно получено через Reflection.

Ошибки и границы. Официальная страница явно упоминает: ReflectionException. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::__constructСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
echo 'Zend-расширение: ', $r->getName(), "\n";
Ожидаемый результат
Zend-расширение: Zend OPcache

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Создать описание ZendExtension по конкретному имени или объекту и получить ошибку для неизвестной цели. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::exportРазобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

PHP 5 >= 5.4.0, PHP 7 · Reflection

public static function ReflectionZendExtension::export(string $name, bool $return = false): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат ReflectionZendExtension::exportСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
echo "export удалён\n";
echo 'замена: ', $r->getName(), "\n";
Ожидаемый результат
export удалён
замена: Zend OPcache

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Разобрать удалённый метод export и заменить его явным созданием Reflection-объекта и контролируемым выводом. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::getAuthorПолучить author из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::getAuthor(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить author из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::getAuthorСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$value = $r->getAuthor();
echo 'getAuthor: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getAuthor: Zend Technologies

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить author из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::getCopyrightПолучить copyright из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::getCopyright(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить copyright из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::getCopyrightСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$value = $r->getCopyright();
echo 'getCopyright: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getCopyright: Copyright (c)

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить copyright из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::getNameПолучить name из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::getName(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить name из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::getNameСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$value = $r->getName();
echo 'getName: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getName: Zend OPcache

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить name из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::getURLПолучить u r l из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::getURL(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить u r l из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::getURLСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$value = $r->getURL();
echo 'getURL: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getURL: http://www.zend.com/

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить u r l из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::getVersionПолучить version из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::getVersion(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить version из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::getVersionСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$value = $r->getVersion();
echo 'getVersion: ', reflectionLabValue($value), "\n";
Ожидаемый результат
getVersion: 8.5.11

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить version из уже выбранного ReflectionZendExtension и использовать результат без исполнения исследуемого кода, если метод только читает метаданные. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

ReflectionZendExtension::__toStringПолучить встроенное текстовое диагностическое представление ReflectionZendExtension; формат не является стабильным API.

PHP 5 >= 5.4.0, PHP 7, PHP 8 · Reflection

public function ReflectionZendExtension::__toString(): string

Зачем открывать эту карточку. CLI-диагностика проверяет возможности установленного PHP и объясняет расхождение между окружениями.

Получить встроенное текстовое диагностическое представление ReflectionZendExtension; формат не является стабильным API.

ПараметрЧто именно передать
Параметров нетМетод читает уже выбранный объект Reflection или его метаданные.

Возврат. Возвращаемый тип: string. Обработайте nullable/false и конкретный подкласс до использования.

Ошибки и границы. Помимо TypeError для неверного типа возможна ошибка, если имя/состояние исследуемого элемента не соответствует контракту. Не превращайте исключение Reflection в молчаливое «элемента нет»: отличайте неизвестное имя, неподходящее состояние и ожидаемый пустой результат.

Увидеть результат ReflectionZendExtension::__toStringСамостоятельный пример
<?php
declare(strict_types=1);

function reflectionLabValue(mixed $value): string
{
    if ($value === null) return 'null';
    if ($value === false) return 'false';
    if ($value === true) return 'true';
    if ($value instanceof UnitEnum) {
        return $value::class . '::' . $value->name;
    }
    if ($value instanceof ReflectionParameter) {
        return 'ReflectionParameter:$' . $value->getName();
    }
    if ($value instanceof ReflectionClassConstant) {
        return 'ReflectionClassConstant:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionAttribute) {
        return 'ReflectionAttribute:' . $value->getName();
    }
    if ($value instanceof ReflectionProperty) {
        return 'ReflectionProperty:' . $value->getDeclaringClass()->getShortName() . '::$' . $value->getName();
    }
    if ($value instanceof ReflectionMethod) {
        return 'ReflectionMethod:' . $value->getDeclaringClass()->getShortName() . '::' . $value->getName();
    }
    if ($value instanceof ReflectionFunctionAbstract) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionClass) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionExtension || $value instanceof ReflectionZendExtension) {
        return $value::class . ':' . $value->getName();
    }
    if ($value instanceof ReflectionType) {
        return $value::class . ':' . (string) $value;
    }
    if ($value instanceof Closure) return 'Closure';
    if ($value instanceof Generator) return 'Generator';
    if ($value instanceof Fiber) return 'Fiber';
    if (is_object($value)) return 'object:' . $value::class;
    if (is_string($value)) return $value;
    if (is_int($value) || is_float($value)) return (string) $value;
    if (is_array($value)) {
        $parts = [];
        foreach ($value as $key => $item) {
            if (is_object($item)) {
                $parts[] = reflectionLabValue($item);
            } elseif (is_scalar($item) || $item === null) {
                $parts[] = (is_string($key) ? $key . '=' : '') . reflectionLabValue($item);
            } elseif (is_array($item)) {
                $parts[] = (is_string($key) ? $key . '=' : '') . 'array(' . count($item) . ')';
            } else {
                $parts[] = (string) $key . '=' . get_debug_type($item);
            }
        }
        sort($parts);
        return 'array(' . count($value) . '): ' . implode(', ', array_slice($parts, 0, 8));
    }
    return get_debug_type($value);
}

$r = new ReflectionZendExtension('Zend OPcache');
$text = (string) $r;
echo 'содержит OPcache: ', str_contains($text, 'OPcache') ? 'да' : 'нет', "\n";
Ожидаемый результат
содержит OPcache: да

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Получить встроенное текстовое диагностическое представление ReflectionZendExtension; формат не является стабильным API. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

Reflector::exportИсторическая статическая выгрузка Reflection, удалённая из PHP; перейти на явные объекты и __toString.

PHP 5, PHP 7 · Reflection

public static function Reflector::export(): string

Зачем открывать эту карточку. Локальная CLI-команда строит компактный отчёт о классе/функции, чтобы проверить версию клиента или контракт плагина.

Историческая статическая выгрузка Reflection, удалённая из PHP; перейти на явные объекты и __toString.

ПараметрЧто именно передать
Историческая сигнатураМетод удалён из текущего PHP; параметры показаны в подписи и на официальной странице версии.

Возврат. В PHP 8.5 метода нет: попытка вызвать его завершится Error. Карточка показывает поддерживаемую замену.

Ошибки и границы. Текущий PHP 8.5 не предоставляет этот метод. Современный пример не вызывает удалённый API.

Увидеть результат Reflector::exportСамостоятельный пример
<?php
declare(strict_types=1);

$reflection = new ReflectionClass(DateTimeImmutable::class);
echo "Reflector::export удалён\n";
echo 'явный объект: ', $reflection->getShortName(), "\n";
Ожидаемый результат
Reflector::export удалён
явный объект: DateTimeImmutable

Пример использует только локальные учебные объявления. Строка результата показывает именно ответ метода, а не делает вывод о бизнес-правах или корректности всего приложения. Если метод исполняет callback, вызывает функцию либо меняет объект, это действие подписано в коде и проверяется следующим чтением состояния.

Как прочитать вывод. Результат относится к учебному объявлению из кода: Историческая статическая выгрузка Reflection, удалённая из PHP; перейти на явные объекты и __toString. В другом классе данные изменятся, а тип/ошибки/граница версии останутся договором метода.

Когда выбрать соседний инструмент. Если задача решается прямым типизированным вызовом, IDE или явной фабрикой, они обычно читаются проще. Reflection нужен, когда библиотека должна исследовать заранее неизвестное объявление по контролируемым правилам.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.