jasny / meta
v3.0.3
2016-08-09 11:50 UTC
Requires
- php: >=5.6.0
- jasny/typecast: ~2.1.0
Requires (Dev)
- jasny/php-code-quality: ^1.1.0
README
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);
在这里
$source
是Jasny\Meta\Source\SourceInterface
的实现 - 从类获取元数据并将其作为关联数组返回$cache
是Jasny\Meta\Cache\CacheInterface
的实现 - 处理元数据的缓存- 返回的
$meta
是Jasny\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' ] ] ]
在这里我们使用了两个额外的依赖项
Jasny\ReflectionFactory\ReflectionFactory
- 创建反射的类,定义在 Jasny Reflection factoryJasny\PhpdocParser\PhpdocParser
- 解析文档注释的类,定义在 Jasny PHPDoc parser
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
类实现了这些方法的前三个(即get
、is
和has
)。