Компонент PropertyInfo
Дата оновлення перекладу 2025-01-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(
- // Список екстракторів [ $reflectionExtractor, $doctrineExtractor ], // Тип екстракторів [ $doctrineExtractor, $reflectionExtractor ]
);
Вилучена інформація
Клас PropertyInfoExtractor демонструє публічні методи для виучення декількох типів інформації:
- Список властивостей : getProperties()
- Тип властивості : getTypes() (включно з типізованими властивостями)
- Опис властивості : getShortDescription() та getLongDescription()
- Доступ до деталей властивості : isReadable() та 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, надають обʼємну інформацію про тип даних для властивості.
$types = $propertyInfo->getTypes($class, $property); / Приклад результату ------------------ array(1) { [0] => class SymfonyComponentPropertyInfoType (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);
/*
Example Result
--------------
string(79):
Це наступний абзац у DocComment.
Він може охоплювати кілька рядків.
*/
7.1
Інтерфейс PropertyDocBlockExtractorInterface був представлений в Symfony 7.1.
Описова інформація
Екстрактори, які реалізують PropertyDescriptionExtractorInterface, надають короткі та довгі описи з анотації властивостей у вигляді рядків.
$title = $propertyInfo->getShortDescription($class, $property); / Приклад результату ------------------ string(41) "Це перший рядок DocComment." /
$paragraph = $propertyInfo->getLongDescription($class, $property); / Приклад результату ------------------ string(79): Це наступний параграф у DocComment. Він може простягатися на декілька рядків. /
Інформація про доступ
Екстрактори, які реалізують PropertyAccessExtractorInterface, надають інформацію про те, чи можна прочитати або написати властивості у вигляді булевих значень.
$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.
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::getCollectionKeyType()
і Type::getCollectionValueType()
Якщо властивість є набором, можуть бути повернені додаткові типи обʼєктів, як для типу ключів, так і для значень набору (якщо інформація доступна), через методи 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, якщо наявна залежна бібліотека.
use SymfonyComponentPropertyInfoExtractorPhpDocExtractor;
$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.
Використовуючи метадані груп
з компонента Serializer, SerializerExtractor
надає інформацію про список. Цей екстрактор не реєструється автоматично у сервісі
property_info
у фреймворку Symfony.
use DoctrineCommonAnnotationsAnnotationReader; use SymfonyComponentPropertyInfoExtractorSerializerExtractor; use SymfonyComponentSerializerMappingFactoryClassMetadataFactory; use SymfonyComponentSerializerMappingLoaderAnnotationLoader;
- $serializerClassMetadataFactory = new ClassMetadataFactory(
- new AnnotationLoader(new AnnotationReader)
); $serializerExtractor = new SerializerExtractor($serializerClassMetadataFactory);
// опція `serializer_groups` має бути сконфігурована (може бути встановлена як null) $serializerExtractor->getProperties($class, ['serializer_groups' => ['mygroup']]);
Якщо serializer_groups
встановлено як null
, метадані груп серіалізатора не
перевірятимуться, ае ви отримаєте лише властивості, які розглядаються компонентом
Серіалізатор (особливо береться до уваги анотація @Ignore
).
DoctrineExtractor
Note
Цей екстрактор залежить від бібліотек symfony/doctrine-bridge і doctrine/orm.
Використовуючи дані відображення сутності з Doctrine ORM,
DoctrineExtractor надає інформацію
про тип та список. Цей екстрактор не реєструється автоматично сервісом property_info
у фреймворку Symfony.
use DoctrineORMEntityManager; use DoctrineORMToolsSetup; use SymfonyBridgeDoctrinePropertyInfoDoctrineExtractor;
$config = Setup::createAnnotationMetadataConfiguration([__DIR__], true); $entityManager = EntityManager::create([ 'driver' => 'pdo_sqlite', // ... ], $config); $doctrineExtractor = new DoctrineExtractor($entityManager);
// List information. $doctrineExtractor->getProperties($class); // Type information. $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.
Якщо ви включили компоненти PropertyInfo і FrameworkBundle, то ви можете автоматично
реєструвати ваш екстрактор за допомогою сервісу property_info
, визначаючи його в
якості сервісу з одним або декількома наступними тегами:
property_info.list_extractor
, якщо він надає інформацію про список.property_info.type_extractor
, якщо він надає інформацію про тип.property_info.description_extractor
, якщо він надає інформацію про опис.property_info.access_extractor
, якщо він надає інформацію про доступ.property_info.initializable_extractor
якщо він надає інформацію, яку можна ініціювати (перевіряє, чи може властивість бути ініційована через конструктор).