-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[PropertyInfo] Add the doc #5717
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,295 @@ | ||
.. index:: | ||
single: PropertyInfo | ||
single: Components; PropertInfo | ||
|
||
The PropertyInfo Component | ||
========================== | ||
|
||
The PropertyInfo component extracts information about PHP class' properties | ||
using metadata of popular sources. | ||
|
||
The PropertyInfo component is able to extract the following information: | ||
|
||
* List of properties exposed by a class | ||
* Types of a property | ||
* It's short and long DockBlock description | ||
* If the property is readable or writable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would use "and/or" here, as it can be both readable and writable. |
||
|
||
To do so, the component use extractors. It natively support the following | ||
metadata sources: | ||
|
||
* ``ReflectionExtractor``: use the PHP Reflection API (setter type hint, | ||
return and scalar type hint for PHP 7+, accessor methods) | ||
* ``PhpDocExtractor``: use the PHPDoc of properties and accessor methods | ||
* ``DoctrineExtractor``: use metadata provided by the Doctrine ORM | ||
* ``SerializerExtractor``: use groups metadata of the Serializer component | ||
|
||
Custom extractors can be also be registered. | ||
|
||
Installation | ||
------------ | ||
|
||
You can install the component in 2 different ways: | ||
|
||
* :doc:`Install it via Composer </components/using_components>` (``symfony/property-info`` | ||
on `Packagist`_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reference to Packagist at the bottom of the file is missing. |
||
* Use the official Git repository (https://github.com/symfony/PropertyInfo). | ||
|
||
.. include:: /components/require_autoload.rst.inc | ||
|
||
To use the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\PhpDocExtractor`, | ||
install `phpDocumentator Reflection`_. | ||
To use the :class:`Symfony\\Component\\PropertyInfo\\Extractor\\SerializerExtractor` | ||
extractor, install the :doc:`Serializer component </components/serializer>`. | ||
To use the :class:`Symfony\\Bridge\\Doctrine\\PropertyInfo\\DoctrineExtractor`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will be rendered as one paragraph with 3 sentences, all looking like "To use the ...Extractor extractor, install the ... component", which I find a not so nice to read paragraph (it breaks to read flow). A common practice is to document additional dependencies in the related sections in a note directive. For instance, in the "DoctrineExtractor" section, put something like: .. note::
You must install the Doctrine Bridge and the Doctrine ORM to be able
to use this extractor. You can install them by running
``composer require doctrine/orm symfony/doctrine-bridge``. |
||
install the Doctrine Bridge and the `Doctrine ORM`_. | ||
|
||
Usage | ||
----- | ||
|
||
Using the PropertyInfo component is straightforward. You need to register | ||
all metadata extractors you want to use in the constructor of the :class:`Symfony\\Component\\PropertyInfo\\PropertyInfo` | ||
class:: | ||
|
||
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; | ||
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; | ||
use Symfony\Component\PropertyInfo\PropertyInfo; | ||
|
||
$reflectionExtractor = new ReflectionExtractor(); | ||
$phpDocExtractor = new PhpDocExtractor(); | ||
|
||
$propertyInfo = new PropertyInfo( | ||
array($reflectionExtractor), | ||
array($phpDocExtractor, $reflectionExtractor), | ||
array($phpDocExtractor), | ||
array($reflectionExtractor) | ||
); | ||
|
||
An array of implementations of :class:`Symfony\\Component\\PropertyInfo\\PropertyListExtractorInterface` | ||
must be passed as first parameter. These extractors are responsible of extracting | ||
the list of properties of a class. | ||
|
||
An array of implementations of :class:`Symfony\\Component\\PropertyInfo\\PropertyTypeExtractorInterface` | ||
must be passed as second parameter. These extractors are responsible of extracting | ||
types of a property. | ||
|
||
An array of implementations of :class:`Symfony\\Component\\PropertyInfo\\PropertyDescriptionExtractorInterface` | ||
must be passed as third parameter. These extractors are responsible of extracting | ||
short and long DocBlock description of a property. | ||
|
||
Finally, an array of implementations of :class:`Symfony\\Component\\PropertyInfo\\PropertyAccessExtractorInterface` | ||
must be passed as fourth parameter. These extractors are responsible of guessing | ||
if a property is readable or writable. | ||
|
||
The order of registration matter: the data returned will be the one returned | ||
by the first extractor if different than ``null``. | ||
|
||
|
||
Once instantiated, the ``PropertyInfo`` class can be used to retrieve info | ||
about properties of a class:: | ||
|
||
class MyClass | ||
{ | ||
/** | ||
* The short description of foo. | ||
* | ||
* And here is its extended description. | ||
* | ||
* @var string | ||
*/ | ||
public $foo; | ||
|
||
/** | ||
* Virtual property. | ||
*/ | ||
private function setBar(array $bar) | ||
{ | ||
} | ||
} | ||
|
||
var_dump($propertyInfo->getProperties('MyClass')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to advocate the Symfony VarDumper component a bit, we always use dump($propertyInfo->getProperties('MyClass'));
/* Produces: array(0 => 'foo') */
... |
||
var_dump($propertyInfo->getTypes('MyClass', 'foo')); | ||
var_dump($propertyInfo->getTypes('MyClass', 'bar')); | ||
var_dump($propertyInfo->isReadable('MyClass', 'foo')); | ||
var_dump($propertyInfo->isReadable('MyClass', 'bar')); | ||
var_dump($propertyInfo->isWritable('MyClass', 'foo')); | ||
var_dump($propertyInfo->getShortDescription('MyClass', 'bar')); | ||
var_dump($propertyInfo->getLongDescription('MyClass', 'foo')); | ||
|
||
/* | ||
Output: | ||
array(1) { | ||
[0] => | ||
string(3) "foo" | ||
} | ||
array(1) { | ||
[0] => | ||
class Symfony\Component\PropertyInfo\Type#7 (6) { | ||
private $builtinType => | ||
string(6) "string" | ||
private $nullable => | ||
bool(false) | ||
private $class => | ||
NULL | ||
private $collection => | ||
bool(false) | ||
private $collectionKeyType => | ||
NULL | ||
private $collectionValueType => | ||
NULL | ||
} | ||
} | ||
array(1) { | ||
[0] => | ||
class Symfony\Component\PropertyInfo\Type#129 (6) { | ||
private $builtinType => | ||
string(5) "array" | ||
private $nullable => | ||
bool(false) | ||
private $class => | ||
NULL | ||
private $collection => | ||
bool(true) | ||
private $collectionKeyType => | ||
NULL | ||
private $collectionValueType => | ||
NULL | ||
} | ||
} | ||
bool(true) | ||
bool(false) | ||
bool(true) | ||
string(17) "Virtual property." | ||
string(37) "And here is its extended description." | ||
*/ | ||
|
||
As PHP doesn't support explicit type definition, ``PropertyInfo::getTypes`` | ||
use registered extractors to an array of :class:`Symfony\\Component\\PropertyInfo\\Type` | ||
value objects. | ||
Those object represent complex PHP types. Refer to the API documentation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Those objects |
||
of this class for more details. | ||
|
||
Extractors | ||
---------- | ||
|
||
Symfony is shipped with two extractors in addition to the already presented | ||
``ReflectionExtractor`` and ``PhpDocExtractors``. | ||
Moreover, custom extractors can be created by implementing the extractor | ||
interfaces provided with the PropertyInfo component. | ||
|
||
The ``DoctrineExtractor`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
The Doctrine extractor reuse metadata of the Doctrine ORM to extract the | ||
list of properties and their type. It implements ``PropertyListExtractorInterface`` | ||
and ``PropertyTypeExtractorInterface`` interfaces. | ||
|
||
Instantiate it:: | ||
|
||
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()); | ||
|
||
You can now use it to retrieve information about an entity mapped with Doctrine:: | ||
|
||
use Doctrine\ORM\Mapping\Column; | ||
use Doctrine\ORM\Mapping\Entity; | ||
use Doctrine\ORM\Mapping\Id; | ||
|
||
/** | ||
* @Entity | ||
*/ | ||
class MyEntity | ||
{ | ||
/** | ||
* @Id | ||
* @Column(type="integer") | ||
*/ | ||
public $id; | ||
} | ||
|
||
var_dump($doctrineExtractor->getProperties('MyEntity')); | ||
var_dump($doctrineExtractor->getTypes('MyEntity', 'id')); | ||
|
||
/* | ||
Output: | ||
|
||
array(1) { | ||
[0] => | ||
string(2) "id" | ||
} | ||
array(1) { | ||
[0] => | ||
class Symfony\Component\PropertyInfo\Type#27 (6) { | ||
private $builtinType => | ||
string(3) "int" | ||
private $nullable => | ||
bool(false) | ||
private $class => | ||
NULL | ||
private $collection => | ||
bool(false) | ||
private $collectionKeyType => | ||
NULL | ||
private $collectionValueType => | ||
NULL | ||
} | ||
} | ||
*/ | ||
|
||
Of course you can also register this extractor in the ``PropertyInfo`` class:: | ||
|
||
$propertyInfo = new PropertyInfo( | ||
array($reflectionExtractor, $doctrineExtractor), | ||
array($doctrineExtractor, $phpDocExtractor, $reflectionExtractor) | ||
); | ||
|
||
The ``SerializerExtractor`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
The ``SerializerExtractor`` leverages groups metadata of the Symfony Serializer | ||
Component (2.7+) to list properties having the groups passed in the context. | ||
|
||
Instantiate it:: | ||
|
||
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); | ||
|
||
Usage:: | ||
|
||
use Symfony\Component\Serializer\Annotation\Groups; | ||
|
||
class Foo | ||
{ | ||
/** | ||
* @Groups({"a", "b"}) | ||
*/ | ||
public $bar; | ||
public $baz; | ||
} | ||
|
||
$serializerExtractor->getProperties('Foo', array('serializer_groups' => array('a'))); | ||
/* | ||
Output: | ||
array(1) { | ||
[0] => | ||
string(2) "bar" | ||
} | ||
*/ | ||
|
||
.. _`Packagist`: https://packagist.org/packages/symfony/property-info | ||
.. _`phpDocumentator Reflection`: https://github.com/phpDocumentor/Reflection | ||
.. _`Doctrine ORM`: http://www.doctrine-project.org/projects/orm.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say it's "properties of the PHP class", but I'm not sure (I remember having the same discussion with "the classes constructor").