简体   繁体   中英

How to parse phpdoc property type in Symfony?

I can read custom annotations in Symfony with class Doctrine\\Common\\Annotations\\AnnotationReader .

It looks like below. I have described property:

/**
 * @var array
 * @MappingClient(ignore=true)
 */
protected static $myProperty = [];

And I may parse annotation @MappingClient :

$class = new \ReflectionClass(get_called_class());
$property = $class->getProperty('myProperty');
$annotationReader = new AnnotationReader();
$mappingClient = $annotationReader
    ->getPropertyAnnotation($property, 'MyClass\Annotation\MappingClient');

And also I need to parse type of property, what described in @var array . I understand what I can parse it with regex on $property->getDocComment() . But how may I do it just with Symfony classes if getPropertyAnnotation() ignoring @var and other standard declarations? Is there a more elegant way of?

If you use Symfony 2.8 or Symfony 3 you can use the PropertyInfo component . It does exactly that.

In a controller:

$this->get('property_info')->getTypes('FooClass', 'foo'); // Must be enabled in the framework configuration
// 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
//   }
// }

I solved this with extension on AnnotationReader:

namespace MyPath\Annotation;

use Doctrine\Common\Annotations\AnnotationReader;

class UniversalAnnotationReader extends AnnotationReader
{
    /**
     * Get type of property from property declaration
     *
     * @param \ReflectionProperty $property
     *
     * @return null|string
     */
    public function getPropertyType(\ReflectionProperty $property)
    {
        $doc = $property->getDocComment();
        preg_match_all('#@(.*?)\n#s', $doc, $annotations);
        if (isset($annotations[1])) {
            foreach ($annotations[1] as $annotation) {
                preg_match_all('#\s*(.*?)\s+#s', $annotation, $parts);
                if (!isset($parts[1])) {
                    continue;
                }
                $declaration = $parts[1];
                if (isset($declaration[0]) && $declaration[0] === 'var') {
                    if (isset($declaration[1])) {
                        if (substr($declaration[1], 0, 1) === '$') {
                            return null;
                        }
                        else {
                            return $declaration[1];
                        }
                    }
                }
            }
            return null;
        }
        return $doc;
    }
}

And how I use this:

$annotationReader = new UniversalAnnotationReader();

$class = new \ReflectionClass(get_called_class());
$type = $annotationReader->getPropertyType($class->getProperty('myProperty'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM