jasny/meta

此包已被弃用且不再维护。作者建议使用 jasny/phpdoc-parser 包。

为类、属性和函数定义元数据

v3.0.3 2016-08-09 11:50 UTC

This package is auto-updated.

Last update: 2023-06-12 21:17:25 UTC


README

Build Status Coverage Status

Jasny Meta 库允许您将元数据附加到类及其属性。这些元数据在运行时可用,并可用于触发特定行为。

安装

Jasny Meta 包可在 packagist 上找到。使用 composer 安装。

composer require jasny/meta

注解

元数据可以通过注解指定。在 PHP 中,注解以 docblock 的形式编写,并以 @ 开头。如果您熟悉编写 docblock,您可能已经认识它们。

以下是一个获取给定类元数据的示例

use Jasny\Meta\Factory;

$factory = new Factory($source, $cache);
$meta = $factory->forClass(FooBar::class);

在这里

  • $sourceJasny\Meta\Source\SourceInterface 的实现 - 从类获取元数据并将其作为关联数组返回
  • $cacheJasny\Meta\Cache\CacheInterface 的实现 - 处理元数据的缓存
  • 返回的 $metaJasny\Meta\MetaClass 的实例。

让我们仔细看看这些。

元数据来源

来源是实际从类定义中获取元数据的对象。我们定义了三种来源类

  • Jasny\Meta\Source\PhpdocSource - 用于从文档注释中获取元数据
  • Jasny\Meta\Source\ReflectionSource - 使用反射方法获取一些通用信息
  • Jasny\Meta\Source\CombinedSource - 一个使用其他来源获取元数据并将其合并为单个输出数组的类

PhpdocSource

给定一个类

/**
 * Original FooBar class
 *
 * @package FoosAndBars
 * @author Jimi Hendrix <jimi-guitars@example.com>
 */
class FooBar
{
    /**
     * Very first property
     * @var array
     * @required
     */
    public $first;

    /**
     * And some more property
     * @var string|Foo
     * @version 3.4
     * @default 'a_place_for_foo'
     */
    public $secondFoo;

    /**
     * Protected properties are not included in fetched meta
     * @var int
     */
    protected $third;

    /**
     * Privates also are not included
     * @var array
     */
    private $fourth;

    //Methods and constants are not included in meta for now
}

我们获取元数据

use Jasny\Meta\Source\PhpdocSource;
use Jasny\ReflectionFactory\ReflectionFactory;
use Jasny\PhpdocParser\PhpdocParser;
use Jasny\PhpdocParser\Set\PhpDocumentor;

$reflectionFactory = new ReflectionFactory();

$tags = PhpDocumentor::tags();
$phpdocParser = new PhpdocParser($tags);

$source = new PhpdocSource($reflectionFactory, $phpdocParser);
$meta = $source->forClass(FooBar::class);

var_export($meta);
[
    'package' => 'FoosAndBars',
    'author' => [
        'name' => 'Jimi Hendrix',
        'email' => 'jimi-guitars@example.com'
    ],
    '@properties' => [
        'first' => [
            'var' => 'array',
            'required' => true
        ],
        'secondFoo' => [
            'var' => 'string|Foo',
            'version' => '3.4',
            'default' => 'a_place_for_foo'
        ]
    ]
]

在这里我们使用了两个额外的依赖项

ReflectionSource

此类不从文档注释中获取任何信息,而是仅使用反射方法获取数据。

使用上一个示例中的类作为输入,我们获取元数据

use Jasny\Meta\Source\ReflectionSource;
use Jasny\ReflectionFactory\ReflectionFactory;

$reflectionFactory = new ReflectionFactory();

$source = new ReflectionSource($reflectionFactory);
$meta = $source->forClass(FooBar::class);

var_export($meta);
[
    'name' => 'Some\\Namespace\\FoosAndBars',
    'title' => 'foos and bars',
    '@properties' => [
        'first' => [
            'name' => 'first',
            'title' => 'first',
            'default' => null
        ],
        'secondFoo' => [
            'name' => 'secondFoo',
            'title' => 'second foo',
            'default' => 'a_place_for_foo'
        ]
    ]
]

$reflectionFactory 依赖项与上面示例中为 PhpdocSource 定义的相同。

CombinedSource

以下是对相同类定义的示例

$sources = [$phpdocSource, $reflectionSource];
$source = new CombinedSource($sources);
$meta = $source->forClass(FooBar::class);

var_export($meta);
[
    'package' => 'FoosAndBars',
    'author' => [
        'name' => 'Jimi Hendrix',
        'email' => 'jimi-guitars@example.com'
    ],
    'name' => 'Some\\Namespace\\FoosAndBars',
    'title' => 'foos and bars',
    '@properties' => [
        'first' => [
            'var' => 'array',
            'required' => true,
            'name' => 'first',
            'title' => 'first',
            'default' => null
        ],
        'secondFoo' => [
            'var' => 'string|Foo',
            'version' => '3.4',
            'name' => 'secondFoo',
            'title' => 'second foo',
            'default' => 'a_place_for_foo'
        ]
    ]
]

如您所见,通过 $phpdocSource$reflectionSource 获取的元数据已合并到单个数组中。

缓存

传递给工厂构造函数的第二个参数是 Jasny\Meta\Cache\CacheInterface 的实例。它用于在调用同一类名之间缓存元数据。

我们有两种缓存实现

  • Jasny\Meta\Cache\None - 实际上不执行任何缓存,用于简化使用缓存的代码
  • Jasny\Meta\Cache\Simple - 将缓存存储到进程内存(因此是数组)。这个缓存不会在不同的PHP进程间持久化,它的生命周期直到当前进程结束。

所以,如果您不想缓存元数据,只需使用$cache = new Jasny\Meta\Cache\None()

元数据

由工厂返回的元数据是Jasny\Meta\MetaClass的一个实例。它有以下方法来获取数据

  • get(string $key, $default = null) - 通过键获取类元数据
  • is(string $key): bool - 检查元数据键是否存在且不为空
  • has(string $key): bool - 检查元数据键是否存在(可以为空)
  • getProperty(string $name): ?MetaProperty - 获取给定类属性的元数据。结果要么是null(如果属性不存在),要么是一个Jasny\Meta\MetaProperty的实例
  • getProperties(): array - 将所有类属性的元数据作为Jasny\Meta\MetaProperty对象的数组获取

MetaProperty类实现了这些方法的前三个(即getishas)。