如何在Symfony中解析phpdoc属性类型?

3

我可以使用Doctrine\Common\Annotations\AnnotationReader类在Symfony中读取自定义注释。

它看起来像下面这样。我已经描述了属性:

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

我可以解析注释@MappingClient

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

我还需要解析属性类型,这在@var array中描述。我知道可以使用$property->getDocComment()上的正则表达式来解析它。但是如果getPropertyAnnotation()忽略了@var和其他标准声明,我该如何只使用Symfony类来完成?是否有更加优雅的方法?

2个回答

3
如果您使用Symfony 2.8或Symfony 3,可以使用PropertyInfo组件。它正是这样做的。
在控制器中:
$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
//   }
// }

1
我用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;
    }
}

如何使用这个:

$annotationReader = new UniversalAnnotationReader();

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接