PHP is a weakly typed programming language. This means that you don't have to
declare the type of the variables (e.g. int
, bool
) and you can store
different kinds of data (e.g. numbers and strings) in the same variable.
Developers have partially overcome this constraint thanks to type hints, phpDoc and, starting from PHP 7, return type declarations. However, in some cases is still necessary to know the type of the PHP properties. That's why Symfony has added a new component called PropertyInfo.
Given a PHP class, this component gets information about all its properties by introspecting several metadata providers, such as Doctrine ORM mapping, phpDoc comments, PHP type hints, serializer metadata, etc.
Consider the following PHP class of a Doctrine entity, which contains different types of properties:
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
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @Entity
*/
class FooClass
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
public $id;
/**
* This is a date (short description).
*
* With a long description.
*
* @var \DateTime
*/
public $foo;
private $bar;
public function setBar(\SplFileInfo $bar)
{
$this->bar = $bar;
}
}
Before using the PropertyInfo component to extract information, you must create
and configure the metadata extractors to use (ReflectionExtractor
,
PhpDocExtractor
, DoctrineExtractor
and SerializerExtractor
are
built-in, but you can create your own extractors too):
1 2 3 4 5 6 7 8
use Symfony\Component\PropertyInfo\PropertyInfo;
$propertyInfo = new PropertyInfo(
array($reflectionExtractor),
array($doctrineExtractor, $phpDocExtractor, $reflectionExtractor),
array($phpDocExtractor),
array($reflectionExtractor)
);
Now you can introspect each property type as follows:
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 32 33 34 35 36 37 38
$propertyInfo->getTypes('FooClass', 'foo');
// array(1) {
// [0] =>
// class Symfony\Component\PropertyInfo\Type#36 (6) {
// private $builtinType => string(6) "object"
// private $nullable => bool(false)
// private $class => string(8) "DateTime"
// private $collection => bool(false)
// private $collectionKeyType => NULL
// private $collectionValueType => NULL
// }
// }
$propertyInfo->getTypes('FooClass', 'id');
// array(1) {
// [0] =>
// class Symfony\Component\PropertyInfo\Type#36 (6) {
// private $builtinType => string(3) "int"
// private $nullable => bool(false)
// private $class => NULL
// private $collection => bool(false)
// private $collectionKeyType => NULL
// private $collectionValueType => NULL
// }
// }
$propertyInfo->getTypes('FooClass', 'bar');
// array(1) {
// [0] =>
// class Symfony\Component\PropertyInfo\Type#245 (6) {
// private $builtinType => string(6) "object"
// private $nullable => bool(false)
// private $class => string(11) "SplFileInfo"
// private $collection => bool(false)
// private $collectionKeyType => NULL
// private $collectionValueType => NULL
// }
// }
This component includes other utilities to extract useful information:
1 2 3 4 5 6 7 8 9 10 11 12 13
$propertyInfo->getProperties('FooClass');
// ['id', 'foo', 'Bar']
$propertyInfo->isReadable('FooClass', 'id'); // true
$propertyInfo->isReadable('FooClass', 'bar'); // false
$propertyInfo->isWritable('FooClass', 'foo'); // true
$propertyInfo->isWritable('FooClass', 'bar'); // true
$propertyInfo->getShortDescription('FooClass', 'foo');
// "This is a date (short description)."
$propertyInfo->getLongDescription('FooClass', 'foo');
// "With a long description."
The link to the source on http://symfony.com/components/PropertyInfo results in a 404... I think the correct URL should be https://github.com/symfony/property-info
Anyway.. the PropertyInfo looks very usefull.
@Jan the "http://symfony.com/components/PropertyInfo" link works for me. The current page is almost empty because the component is very new (we lack its documentation, the list of projects using it, etc.)
As the documentation PR has not been merged yet, people might want to have a look at https://github.com/symfony/symfony-docs/pull/5717 and Platform.sh deployed version http://pr-5717-6qmocelev2lwe.eu.platform.sh/components/property_info.html :) Also this component is used in api-platform if some search for concrete usages.
@Javier: @Jan was talking about the "Code" link on the mentioned page, which should point to https://github.com/symfony/property-info instead of https://github.com/symfony/PropertyInfo
@Maxime, you are right. This issue is being fixed right now and the solution will be deployed soon. Thanks.
Nice, so it are those well known "New in Symfony 2.x" weeks. Always like those times, they feel like Christmas ;-)
I don't see any Doctrine extractor in the current code base. Is it a WIP?
@Thomas the Doctrine extractor is in the Doctrine Bridge: https://github.com/symfony/symfony/blob/2.8/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
@Kevin Oh okay, thanks!