Компонент PropertyInfo (Информация о свойстве)

Компонент PropertyInfo (Информация о свойстве)

Компонент PropertyInfo позволяет вам получать информацию о свойствах класса, используя разные источники метаданных.

В то время, как компонент PropertyAccess component позволяет вам читать и писать значение из,в объекты и массиві, компонент PropertyInfo работает только с определениями классов, чтобы предоставить информацию о типе данных и видимости свойств в этом классе, включая геттер и сеттер методы.

Установка

1
$ composer require symfony/property-info

Также вы можете клонировать репозиторий https://github.com/symfony/property-info.

Note

Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно подключить файл vendor/autoload.php в вашем коде для включения механизма автозагрузки классов, предоставляемых Composer. Детальнее читайте в этой статье.

Дополнительные зависимости могут быть необходимы для некоторых из извлекателей, предоставленных этим компонентом.

Использование

Чтобы использовать этот компонент создайте новый экземпляр PropertyInfoExtractor и предоставьте ему набор извлекателей информации.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Example\Namespace\YourAwesomeCoolClass;

// полный список извлекателей показан ниже
$phpDocExtractor = new PhpDocExtractor();
$reflectionExtractor = new ReflectionExtractor();

// массив PropertyListExtractorInterface
$listExtractors = array($reflectionExtractor);

// массив PropertyTypeExtractorInterface
$typeExtractors = array($phpDocExtractor, $reflectionExtractor);

// массив PropertyDescriptionExtractorInterface
$descriptionExtractors = array($phpDocExtractor);

// массив PropertyAccessExtractorInterface
$accessExtractors = array($reflectionExtractor);

$propertyInfo = new PropertyInfoExtractor(
    $listExtractors,
    $typeExtractors,
    $descriptionExtractors,
    $accessExtractors
);

// см. далее, чтобы увидеть больше примеров
$class = YourAwesomeCoolClass::class;
$properties = $propertyInfo->getProperties($class);

Порядок извлекателей

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

Например, в то время, как все класс ReflectionExtractor и DoctrineExtractor оба оба предоставляют информацию о списке, наверное будет лучше, чтобы:

  • ReflectionExtractor имел приоритет для информации о списке, чтобы все свойства в классе были возвращены (а не только отображённые свойства).
  • DoctrineExtractor имел приоритет для информации о типе, чтобы метаданные сущности были использованы вместо типизирования, чтобы предоставить более точную информацию о типе.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;

$reflectionExtractor = new ReflectionExtractor();
$doctrineExtractor = new DoctrineExtractor(/* ... */);

$propertyInfo = new PropertyInfoExtractor(
    // Извлекатели списка
    array(
        $reflectionExtractor,
        $doctrineExtractor
    ),
    // Извлекатели типа
    array(
        $doctrineExtractor,
        $reflectionExtractor
    )
);

Извлекаемая информация

Класс PropertyInfoExtractor демонстрирует публичные методы для извлечения четырёх типов в информации:

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, предоставляют список в свойств, которые доступны в классе в качестве массива, содержащий каждое имя свойства в виде строки.

1
2
3
4
5
6
7
8
9
10
$properties = $propertyInfo->getProperties($class);
/*
  Пример результата
  -----------------
  array(3) {
    [0] => string(8) "username"
    [1] => string(8) "password"
    [2] => string(6) "active"
  }
*/

Информация о типе

Извлекатели, которые реализуют PropertyTypeExtractorInterface, предоставляют extensive data type information для свойства.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$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
    }
  }
*/

См. Компонент PropertyInfo (Информация о свойстве), чтобы получить информацию о классе Type.

Информация об описании

Извлекатели, которые реализуют 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.

4.1

Поддержка методов хассера в классе ReflectionExtractor была представлена в Symfony 4.1.

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 , которые определяются в виде списка префиксов заглушителей массива.

Type::getCollectionKeyType() & Type::getCollectionValueType()

Если свойство является набором, могут быть возвращены дополнительные типы объектов, как для типа ключей, так и значений набора (если информация доступна), через методы Type::getCollectionKeyType() и Type::getCollectionValueType().

Извлекатели

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

Класс PropertyInfoExtractor итерирует соответствующие классы извлекателей, в том порядке, в котором они были установлены, вызывает соответствующий метод и возвращает первый результат, который не является null.

Несмотря на то, что вы можете создавать свои собственные извлекатели, следующие уже доступны для того, чтобы охватить большинство случаев использования:

ReflectionExtractor

Используя отображение PHP, ReflectionExtractor предоставляет информацию о типе, списке и доступе из методов сеттера и процесса доступа. Он также может предоставить возвратный и скалярный тип для PHP 7+.

Note

При использовании фреймворка Symfony, этот сервис автоматически регистрируется, когда включена функция property_info:

1
2
3
4
# config/packages/framework.yaml
framework:
    property_info:
        enabled: true
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;

$reflectionExtractor = new ReflectionExtractor();

// Информация о списке.
$reflectionExtractor->getProperties($class);
// Информация о типе.
$reflectionExtractor->getTypes($class, $property);
// Информация доступа.
$reflectionExtractor->isReadable($class, $property);
$reflectionExtractor->isWritable($class, $property);

PhpDocExtractor

Note

Этот извлекатель зависит от библиотеки phpdocumentor/reflection-docblock.

Используя Отражение phpDocumentor для анализа свойства и метода аннотации, PhpDocExtractor предоставляет информацию о типе и описании. Этот извлекатель автоматически регистрируются с помощью property_info в фреймворке Symfony, если присутствует зависимая библиотека.

1
2
3
4
5
6
7
8
9
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;

$phpDocExtractor = new PhpDocExtractor();

// Информация о типе.
$phpDocExtractor->getTypes($class, $property);
// Информация об описании.
$phpDocExtractor->getShortDescription($class, $property);
$phpDocExtractor->getLongDescription($class, $property);

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);

// Информация о списке
$serializerExtractor->getProperties($class);

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->getMetadataFactory());

// Информация о списке.
$doctrineExtractor->getProperties($class);
// Информация о типе.
$doctrineExtractor->getTypes($class, $property);

Создание ваших собственных извлекателей

Вы можете создавать ваши собственные извлекатели информации свойства, создавая класс, реализующий один или более следующих интерфейсов PropertyAccessExtractorInterface, PropertyDescriptionExtractorInterface, PropertyListExtractorInterface и PropertyTypeExtractorInterface.

Если вы включили компонент PropertyInfo и FrameworkBundle, то вы можете автоматически регистрировать ваш извлекатель с помощью сервиса property_info, определяя его в качестве сервиса с одним или несколькими следующими тегами:

  • property_info.list_extractor, если он предоставляет информацию о списке.
  • property_info.type_extractor, если он предоставляет информацию о типе.
  • property_info.description_extractor, если он предоставляет информацию об описании.
  • property_info.access_extractor, если он предоставляет информацию о доступе.