Компонент PropertyInfo (Информация о свойстве)
Дата обновления перевода 2024-07-10
Компонент PropertyInfo (Информация о свойстве)
Компонент PropertyInfo позволяет вам получать информацию о свойствах класса, используя разные источники метаданных.
В то время, как компонент PropertyAccess позволяет вам читать и писать значение из,в объекты и массиві, компонент PropertyInfo работает только с определениями классов, чтобы предоставить информацию о типе данных и видимости свойств в этом классе, включая геттер и сеттер методы.
Установка
1
$ composer require symfony/property-info
Note
Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно
подключить файл vendor/autoload.php
в вашем коде для включения механизма
автозагрузки классов, предоставляемых Composer. Детальнее читайте в
этой статье.
Дополнительные зависимости могут быть необходимы для некоторых из экстракторов, предоставленных этим компонентом .
Использование
Чтобы использовать этот компонент создайте новый экземпляр PropertyInfoExtractor и предоставьте ему набор экстракторов информации.
use ExampleNamespaceYourAwesomeCoolClass; use SymfonyComponentPropertyInfoExtractorPhpDocExtractor; use SymfonyComponentPropertyInfoExtractorReflectionExtractor; use SymfonyComponentPropertyInfoPropertyInfoExtractor;
// полный список экстракторов показан ниже $phpDocExtractor = new PhpDocExtractor(); $reflectionExtractor = new ReflectionExtractor();
// список PropertyListExtractorInterface (любое итерируемое) $listExtractors = [$reflectionExtractor];
// список PropertyTypeExtractorInterface (любое итерируемое) $typeExtractors = [$phpDocExtractor, $reflectionExtractor];
// список PropertyDescriptionExtractorInterface (любое итерируемое) $descriptionExtractors = [$phpDocExtractor];
// список PropertyAccessExtractorInterface (любое итерируемое) $accessExtractors = [$reflectionExtractor];
// список PropertyInitializableExtractorInterface (любое итерируемое) $propertyInitializableExtractors = [$reflectionExtractor];
- $propertyInfo = new PropertyInfoExtractor(
- $listExtractors, $typeExtractors, $descriptionExtractors, $accessExtractors, $propertyInitializableExtractors
);
// см. далее, чтобы увидеть больше примеров $class = YourAwesomeCoolClass::class; $properties = $propertyInfo->getProperties($class);
Порядок экстракторов
Порядок экземпляров экстракторов в массиве имеет значение: первый результат который не будет null, будет возвращен. Поэтому вы должны предоставить каждой категории экстракторов отдельные массивы, даже если экстрактор предоставляет информацию для более, чем одной категории.
Например, в то время, как все класс ReflectionExtractor и DoctrineExtractor оба оба предоставляют информацию о списке, наверное будет лучше, чтобы:
- ReflectionExtractor имел приоритет для информации о списке, чтобы все свойства в классе были возвращены (а не только отображённые свойства).
DoctrineExtractor имел приоритет для информации о типе, чтобы метаданные сущности были использованы вместо типизирования, чтобы предоставить более точную информацию о типе.
use SymfonyBridgeDoctrinePropertyInfoDoctrineExtractor; use SymfonyComponentPropertyInfoExtractorReflectionExtractor; use SymfonyComponentPropertyInfoPropertyInfoExtractor;
$reflectionExtractor = new ReflectionExtractor(); $doctrineExtractor = new DoctrineExtractor(/ ... /);
- $propertyInfo = new PropertyInfoExtractor(
- // Экстраторы списка array( $reflectionExtractor, $doctrineExtractor ), // Экстраторы типа array( $doctrineExtractor, $reflectionExtractor )
);
Извлекаемая информация
Класс PropertyInfoExtractor демонстрирует публичные методы для извлечения четырёх типов в информации:
- Список свойств : getProperties()
- Тип свойства : getTypes() (включая типизированные свойства)
- Описание свойства : getShortDescription() and getLongDescription()
- Детали доступа к свойству : isReadable() and isWritable()
- Свойство, иницализируемое через конструктор : isInitializable()
Note
Передайте имя класса, а не объекта, методам экстрактора:
1 2 3 4 5 6 7
// Плохо! Может сработать, но не со всеми экстракторами
$propertyInfo->getProperties($awesomeObject);
// Хорошо!
$propertyInfo->getProperties(get_class($awesomeObject));
$propertyInfo->getProperties('Example\Namespace\YourAwesomeClass');
$propertyInfo->getProperties(YourAwesomeClass::class);
Информация о списке
Экстракторы, которые реализуют PropertyListExtractorInterface, предоставляют список в свойств, которые доступны в классе в качестве массива, содержащий каждое имя свойства в виде строки.
$properties = $propertyInfo->getProperties($class); / Пример результата ----------------- array(3) { [0] => string(8) "username" [1] => string(8) "password" [2] => string(6) "active" } /
Информация о типе
Экстракторы, которые реализуют PropertyTypeExtractorInterface, предоставляют расширенную информацию типа данных для свойства:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$types = $propertyInfo->getTypes($class, $property);
/*
Пример результата
-----------------
array(1) {
[0] =>
class Symfony\Component\PropertyInfo\Type (6) {
private $builtinType => string(6) "string"
private $nullable => bool(false)
private $class => NULL
private $collection => bool(false)
private $collectionKeyType => NULL
private $collectionValueType => NULL
}
}
*/
См. , чтобы получить информацию о классе Type
.
Блок документации
Экстракторы, реализующие PropertyDocBlockExtractorInterface,
могут предоставить полный блок документации для свойства в виде строки:
1 2 3 4 5 6 7 8
$docBlock = $propertyInfo->getDocBlock($class, $property);
/*
Пример результата
-----------------
string(79):
Это следующий параграф в DocComment.
Он может содержать несколько строк.
*/
7.1
Интерфейс PropertyDocBlockExtractorInterface был представлен в Symfony 7.1.
Информация об описании
Экстракторы, которые реализуют PropertyDescriptionExtractorInterface, предоставляют короткие и длинные описания из аннотации свойств в виде строк:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$title = $propertyInfo->getShortDescription($class, $property);
/*
Пример результата
-----------------
string(41) "Это первая строка DocComment."
*/
$paragraph = $propertyInfo->getLongDescription($class, $property);
/*
Пример результата
-----------------
string(79):
Это следующий параграф в DocComment.
Он может содержать несколько строк.
*/
Информация доступа
Экстракторы, которые реализуют PropertyAccessExtractorInterface, предоставляют информацию о том, можно ли прочитать или написать свойства, в виде булевых значений:
1 2 3 4 5
$propertyInfo->isReadable($class, $property);
// Пример результата: bool(true)
$propertyInfo->isWritable($class, $property);
// Пример результата: bool(false)
ReflectionExtractor ищет методы геттера
/ иссера / сеттера / хассера в дополнение к тому, является ли свойство публичным, чтобы определить,
возможно ли получить к нему доступ. Это основывается на том, как работает
PropertyAccess. Он предполагает использование имен методов
в стиле верблюжьего регистра, следующего за PSR-1. Например, свойства myProperty
и my_property
доступны для чтения, если есть метод getMyProperty()
и для записи, если есть метод setMyProperty()
.
Инициализируемая информация о свойстве
Экстракторы, которые реализуют PropertyInitializableExtractorInterface, предоставляют информацию о том, инициализируемые ли свойства через конструктор класса как булевы значения:
1 2
$propertyInfo->isInitializable($class, $property);
// Пример результата: bool(true)
isInitializable()
возвращает true
, если параметр конструктора заданного класса совпадает с
заданным именем свойства.
Tip
Главный класс PropertyInfoExtractor реализует все интерфейсы, делегируя извлечение информации о свойстве экстракторам, которые были зарегистрированы в нём.
Это означает, что любой метод, доступный в каждом из экстракторов, также доступен в главном классе PropertyInfoExtractor.
Объекты типов
В сравнении с другими экстракторами, экстракторы типа информации предоставляют намного больше информации, чем можно отобразить в обычном скалярном значении. Поэтому, экстракторы типа возвращают массив объектов Type для каждого типа, поддерживаемого свойством.
Например, если свойство поддерживает как integer
, так и string
(через аннотацию
@return int|string
),
PropertyInfoExtractor::getTypes()
вернёт массив содержащий два экземпляра класса Type.
class.
Note
Большинство экстракторов вернут только один экземпляр Type. На данный момент, PhpDocExtractor является единственным экстрактором, который возвращает несколько экземпляров в массиве.
Каждый объект предоставит 6 атрибутов, доступных в 6 методах:
Type::getBuiltInType()
Метод Type::getBuiltinType()
вернёт встроенный тип данных PHP, который может быть одним из этих возможных значений строки:
array
, bool
, callable
, float
, int
, iterable
, null
, object
,
resource
или string
.
Константы внутри класса Type,
в форме Type::BUILTIN_TYPE_*
предоставляются для удобства.
Type::isNullable()
Метод Type::isNullable()
вернёт булево значение, отображающее, может ли параметр свойства быть установлен как
null
.
Type::getClassName()
Если встроенный тип данных PHP - это
object
, метод Type::getClassName()
вернёт полное приемлемое имя класса или интерфейса.
Type::isCollection()
Метод Type::isCollection()
вернёт булево значение, отображающие, является ли свойство параметра набором (нескалярным
значением, способным содержать другие значения). На данный момент, возвращается true
,
если:
- Встроенный тип данных PHP
- это
array
, или - метод заглушения свойства из которого выводится свойство, имеет префикс
add
илиremove
, которые определяются в виде списка префиксов заглушителей массива. - аннотация phpDocumentor имеет тип "коллекция" (например,
@var SomeClass<DateTime>
,@var SomeClass<integer,string>
,@var Doctrine
и т.д.)\Common \Collections \Collection<App \Entity \SomeEntity>
Type::getCollectionKeyTypes()
и Type::getCollectionValueTypes()
Если свойство является набором, могут быть возвращены дополнительные типы объектов, как для типа ключей, так и значений набора (если информация доступна), через методы Type::getCollectionKeyType() и Type::getCollectionValueType().
Note
Псевдотип list
возвращается компонентом PropertyInfo в виде массива
с целым числом в качестве типа ключа.
Экстракторы
Извлечение информации свойства выполняется классами экстракторов. Класс экстрактора может предоставить один или более типов информации свойства, реализуя правильный интерфейс(ы).
Класс PropertyInfoExtractor
итерирует соответствующие классы экстракторов, в том порядке, в котором они
были установлены, вызывает соответствующий метод и возвращает первый результат,
который не является null
.
Несмотря на то, что вы можете создавать свои собственные экстракторы, следующие уже доступны для того, чтобы охватить большинство случаев использования:
ReflectionExtractor
Используя PHP-отражение, ReflectionExtractor предоставляет список, тип и информацию доступа из методов сеттера и аксессора. Он также может предоставить тип свойства (даже извлекая его из аргументов конструктора), и информацию о том, можно ли его инициализировать через конструктор. Он поддерживает возвратные и скалярные типы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
$reflectionExtractor = new ReflectionExtractor();
// Информация о списке.
$reflectionExtractor->getProperties($class);
// Информация о типе.
$reflectionExtractor->getTypes($class, $property);
// Информация доступа.
$reflectionExtractor->isReadable($class, $property);
$reflectionExtractor->isWritable($class, $property);
// Инициализируемая информация
$reflectionExtractor->isInitializable($class, $property);
Note
При использовании фреймворка Symfony, этот сервис автоматически регистрируется,
когда включена функция property_info
:
1 2 3 4
# config/packages/framework.yaml
framework:
property_info:
enabled: true
PhpDocExtractor
Note
Этот экстрактор зависит от библиотеки phpdocumentor/reflection-docblock.
Используя Отражение phpDocumentor для анализа свойства и метода аннотации,
PhpDocExtractor предоставляет
информацию о типе и описании. Этот экстрактор автоматически регистрируются с помощью
property_info
в фреймворке Symfony, если присутствует зависимая библиотека:
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
$phpDocExtractor = new PhpDocExtractor();
// Информация о типе.
$phpDocExtractor->getTypes($class, $property);
// Информация об описании.
$phpDocExtractor->getShortDescription($class, $property);
$phpDocExtractor->getLongDescription($class, $property);
$phpDocExtractor->getDocBlock($class, $property);
7.1
Метод getDocBlock() был представлен в Symfony 7.1.
PhpStanExtractor
Note
Этот экстрактор зависит от библиотек phpstan/phpdoc-parser и phpdocumentor/reflection-docblock.
Этот экстрактор извлекает информацию благодаря парсеру PHPStan. Он собирает
информацию из аннотаций свойств и методов, таких как @var
, @param
или
@return
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// src/Domain/Foo.php
class Foo
{
/**
* @param string $bar
*/
public function __construct(
private string $bar,
) {
}
}
// Extraction.php
use Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor;
use App\Domain\Foo;
$phpStanExtractor = new PhpStanExtractor();
$phpStanExtractor->getTypesFromConstructor(Foo::class, 'bar');
SerializerExtractor
Note
Этот экстрактор зависит от библиотек symfony/serializer.
Использование метаданных групп
из компонента Сериализатор, предоставляет информацию о
списке. Этот экстрактор не регистрируется автоматически в сервисе property_info
в фреймворке Symfony:
1 2 3 4 5 6 7 8 9 10 11 12
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\PropertyInfo\Extractor\SerializerExtractor;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
$serializerClassMetadataFactory = new ClassMetadataFactory(
new AnnotationLoader(new AnnotationReader)
);
$serializerExtractor = new SerializerExtractor($serializerClassMetadataFactory);
// опция `serializer_groups` должна быть сконфигурирована (может быть null)
$serializerExtractor->getProperties($class, ['serializer_groups' => ['mygroup']]);
Если serializer_groups
установлена как null
, метаданные групп сериалиазции не
будут проверены, но вы получите только свойства, которые рассматриваются компонентом
Serializer (что примечательно, аннотация @Ignore
принимается во внимание).
DoctrineExtractor
Note
Этот экстрактор зависит от библиотек symfony/doctrine-bridge и doctrine/orm.
Использование данных отображения сущности из Doctrine ORM,
DoctrineExtractor предоставляет
информацию о типе и списке. Этот экстрактор не регистрируется автоматически сервисом
property_info
в фреймворке Symfony:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
$config = Setup::createAnnotationMetadataConfiguration([__DIR__], true);
$entityManager = EntityManager::create([
'driver' => 'pdo_sqlite',
// ...
], $config);
$doctrineExtractor = new DoctrineExtractor($entityManager);
// Информация о списке.
$doctrineExtractor->getProperties($class);
// Информация о типе.
$doctrineExtractor->getTypes($class, $property);
ConstructorExtractor
ConstructorExtractor пытается извлечь информацию свойств, используя либо PhpStanExtractor, либо ReflectionExtractor в аргументах конструктора:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Domain/Foo.php
class Foo
{
public function __construct(
private string $bar,
) {
}
}
// Extraction.php
use App\Domain\Foo;
use Symfony\Component\PropertyInfo\Extractor\ConstructorExtractor;
$constructorExtractor = new ConstructorExtractor([new ReflectionExtractor()]);
$constructorExtractor->getTypes(Foo::class, 'bar')[0]->getBuiltinType(); // returns 'string'
Создание ваших собственных экстракторов
Вы можете создавать ваши собственные экстракторы информации свойства, создавая класс, реализующий один или более следующих интерфейсов PropertyAccessExtractorInterface, PropertyDescriptionExtractorInterface, PropertyListExtractorInterface, PropertyTypeExtractorInterface и PropertyInitializableExtractorInterface.
Если вы включили компонент PropertyInfo и FrameworkBundle, то вы можете автоматически
регистрировать ваш экстрактор с помощью сервиса property_info
, определяя его в качестве
сервиса с одним или несколькими следующими тегами:
property_info.list_extractor
, если он предоставляет информацию о списке.property_info.type_extractor
, если он предоставляет информацию о типе.property_info.description_extractor
, если он предоставляет информацию об описании.property_info.access_extractor
, если он предоставляет информацию о доступе.property_info.initializable_extractor
, если он предоставляет инициализируемую информацию (проверяет, может ли свойство быть инициализировано через конструктор).