Компонент PropertyInfo
Дата оновлення перекладу 2024-05-03
Компонент 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.
Інформація про властивість, що можна ініціювати
Екстрактори, які реалізують 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
якщо він надає інформацію, яку можна ініціювати (перевіряє, чи може властивість бути ініційована через конструктор).