vox/metadata

1.0.2 2021-11-09 01:12 UTC

This package is auto-updated.

Last update: 2024-09-15 21:32:55 UTC


README

使用 doctrine 注解、php 8 属性或 yaml 文件轻松读取 php 类的元数据。所有元数据都可以使用任何 psr 缓存解决方案或 doctrine 缓存进行缓存,此库还可以读取由 ocramius 代理管理器创建的代理中的数据。

从类型提示(也来自 php 7.4 属性)、docblocks(使用 @var)、返回类型(类型提示和 docblocks)中读取类型

  • 子类
  • 属性
  • 方法
  • 方法属性

此库也支持循环依赖安全。

用法

要读取元数据,您需要一个 MetadataFactory 实例,您可以手动创建它或使用方便的工厂方法

创建元数据工厂实例

有两个元数据工厂工厂方法,一个是基于注解的,另一个是基于 yaml 的

创建注解元数据工厂

$factory = (new MetadataFactoryFactory(debug: false))->createAnnotationMetadataFactory();

构造函数可能接受一个可选参数,用于设置调试开启或关闭

创建 yaml 元数据工厂

$factory = (new MetadataFactoryFactory(debug: true))->createYmlMetadataFactory(__DIR__ . '/../metadata');

工厂方法接口

这些工厂方法有几个选项,请阅读其文档以了解它们

/**
 * @param string $metadataClassName the fqcn to be used as class metadata holder, must implement the interface
 * @param Reader|null $reader the desired annotation reader, a custom one can be derived from the doctrine interface
 * @param string $methodMetadataClassName the fqcn to be used as method metadata holder, must implement the interface
 * @param string $propertyMetadataClassName the fqcn to be used as property metadata holder, must implement the interface
 *
 * @return MetadataFactory
 */
public function createAnnotationMetadataFactory(
    string $metadataClassName = ClassMetadata::class,
    Reader $reader = null,
    string $methodMetadataClassName = MethodMetadata::class,
    string $propertyMetadataClassName = PropertyMetadata::class
);

/**
 * @param string $metadataPath the path for the folder containing the metadata yaml files
 * @param string $metadataClassName the fqcn to be used as class metadata holder, must implement the interface
 * @param string $methodMetadataClassName the fqcn to be used as method metadata holder, must implement the interface
 * @param string $propertyMetadataClassName the fqcn to be used as property metadata holder, must implement the interface
 * @param string $yamlExtension the desired extension for the yaml files
 *
 * @return MetadataFactory
 */
public function createYmlMetadataFactory(
    string $metadataPath,
    string $metadataClassName = ClassMetadata::class,
    string $methodMetadataClassName = MethodMetadata::class,
    string $propertyMetadataClassName = PropertyMetadata::class,
    string $yamlExtension = 'yaml'
);

添加缓存进行优化

此库使用 jms/metadata 实现来存储其元数据,这意味着元数据是完全可序列化和可缓存的。您可以为 Metadata\Cache\CacheInterface 创建自己的缓存实现,但是,此包捆绑了一个 psr-16 简单缓存适配器,请参阅示例

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Vox\Metadata\Cache\PsrSimpleCacheAdapter;

$factory = (new MetadataFactoryFactory(true))->createAnnotationMetadataFactory();

$factory->setCache(new PsrSimpleCacheAdapter(new Psr16Cache(new FileSystemAdapter())));

创建自己的注解

您可以使用两种类型的注解,doctrine 的或 php 8 的属性,如果您想支持 php 7.4 和 8,请查看一个兼容示例

/**
 * @Annotation
 * @NamedArgumentConstructor
 * @Target({"CLASS", "METHOD", "PROPERTY"})
 */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD | Attribute::TARGET_PROPERTY)]
class TestAnnotation
{
    /**
     * @var string
     */
    public string $name = 'default';

    public function __construct($name = 'default')
    {
        $this->name = $name;
    }
}

读取元数据

注释类

/**
 * @Controller() 
 */
class SomeAnnotatedClass {
    private SomeService $service;
    
    /**
     * @var SomeType 
     */
    private $someType;
    
    #[Get('/{id}')]
    public function getData(int $id) {}
}

读取类

$factory = (new MetadataFactoryFactory(true))->createAnnotationMetadataFactory();

$metadata = $factory->getMetadataForClass(SomeAnnotatedClass::class);

$metadata->name; // MyNamespace\\SomeAnnotatedClass
$metadata->getAnnotations(); // [ MyNamespace\\Controller ]
$metadata->getAnnotation(Controller::class); // MyNamespace\\Controller
$metadata->propertyMetadata['service']->type; // MyNamespace\\SomeService
$metadata->propertyMetadata['someType']->type; // MyNamespace\\SomeType
$metadata->methodMetadata['getData']->getAnnotations(); // [ MyNamespace\\Get ]
$metadata->methodMetadata['getData']->params[0]->type; // int