liip/metadata-parser
最新稳定版本:2.0.0
Composer 安装命令:
composer require liip/metadata-parser
包简介
Parser for metadata
README 文档
README
This project is Open Sourced based on work that we did initially as closed source at Liip, it may be lacking some documentation. If there is anything that you need or have questions about we would love to see you open an issue! :)
This is a parser for building model metadata from PHP classes. The metadata model can then be used to generate code or configuration. For example a serializer or ElasticSearch schema for types.
The metadata is geared toward this use case. PHP level constructs that represent the same information are grouped together: Methods for virtual properties and fields that have the same serialized name, but are valid in different versions.
This extensible parser can process PHP code and annotations or other metadata. You could write your own parsers, but this library comes with support for:
- Reflection
- PhpDoc
- JMSSerializer annotations
Contributing
If you want to contribute to the project (awesome!!), please read the Contributing Guidelines and adhere to our Code Of Conduct
Where do I go for help?
If you need, open an issue.
Setup
use Doctrine\Common\Annotations\AnnotationReader; use Liip\MetadataParser\Builder; use Liip\MetadataParser\Parser; use Liip\MetadataParser\RecursionChecker; use Liip\MetadataParser\ModelParser\JMSParser; use Liip\MetadataParser\ModelParser\LiipMetadataAnnotationParser; use Liip\MetadataParser\ModelParser\PhpDocParser; use Liip\MetadataParser\ModelParser\ReflectionParser; use Liip\MetadataParser\ModelParser\VisibilityAwarePropertyAccessGuesser; $parser = new Parser( new ReflectionParser(), new PhpDocParser(), new JMSParser(new AnnotationReader()), new VisibilityAwarePropertyAccessGuesser(), new LiipMetadataAnnotationParser(new AnnotationReader()), ); $recursionChecker = new RecursionChecker(new NullLogger()); $builder = new Builder($parser, $recursionChecker);
Usage
The Builder::build method is the main entry point to get a ClassMetadata
object. The builder accepts an array of Reducer to select which property to
use when there are several options. A reducer can lead to drop a property if
none of the variants is acceptable. Multiple options for a single field mainly
come from the @SerializedName and @VirtualProperty annotations of
JMSSerializer:
- GroupReducer: Select the property based on whether it is in any of the specified groups;
- VersionReducer: Select the property based on whether it is included in the specified version;
- TakeBestReducer: Make sure that we end up with the property that has the same name as the serialized name, if we still have multiple options after the other reducers.
use Liip\MetadataParser\Reducer\GroupReducer; use Liip\MetadataParser\Reducer\PreferredReducer; use Liip\MetadataParser\Reducer\TakeBestReducer; use Liip\MetadataParser\Reducer\VersionReducer; $reducers = [ new VersionReducer('2'), new GroupReducer(['api', 'detail']), new PreferredReducer(), new TakeBestReducer(), ]; $metadata = $builder->build(MyClass::class, $reducers);
The ClassMetadata provides all information on a class. Properties have a
PropertyType to tell what kind of property they are. Properties that hold
another class, are of the type PropertyTypeClass that has the method
getClassMetadata() to get the metadata of the nested class. This structure
is validated to not contain any infinite recursion.
Property naming strategy
By default, property names will be translated from a camelCased to a lower and
snake_cased name (e.g. myProperty becomes my_property). If you want to keep
the property name as is, you can change the strategy to identical by passing
the corresponding strategy to the parser.
use Liip\MetadataParser\Builder; use Liip\MetadataParser\ModelParser\NamingStrategy\IdenticalPropertyNamingStrategy; $identicalNamingStrategy = new IdenticalPropertyNamingStrategy(); $parser = new Parser( [ // your parsers ], new IdenticalPropertyNamingStrategy() ); $builder = new Builder($parser)
You can also create your own naming strategy by implementing the Liip\MetadataParser\ModelParser\NamingStrategy\PropertyNamingStrategyInterface
Handling Edge Cases with @Preferred
This library provides its own annotation in Liip\MetadataParser\Annotation\Preferred
to specify which property to use in case there are several options. This can be
useful for example when serializing models without specifying a version, when
they use different virtual properties in different versions.
use JMS\Serializer\Annotation as JMS; use Liip\MetadataParser\Annotation as Liip; class Product { /** * @JMS\Since("2") * @JMS\Type("string") */ public $name; /** * @JMS\Until("1") * @JMS\SerializedName("name") * @JMS\Type("string") * @Liip\Preferred */ public $legacyName; }
Expected Recursion: Working with Flawed Models
JMS annotation
If you are using JMS annotations, you can add the MaxDepth annotation to
properties that might be recursive.
The following example will tell the metadata parser that the recursion is
expected up to a maximum depth of 3.
use JMS\Serializer\Annotation as JMS; class RecursionModel { /** * @JMS\MaxDepth(3) * @JMS\Type("RecursionModel") */ public $recursion; }
Pure PHP
The RecursionChecker accepts a second parameter to specify places where to break recursion. This is useful if your model tree looks like it has recursions but actually does not have them. JMSSerializer always acts on the actual data and therefore does not notice a recursion as long as it is not infinite.
For example, lets say you have a Product that has a field variants which is
again list of Product. Those variant products use the same class and
therefore have the variants field. However, in real data a variant never
contains further variants. To avoid a recursion exception for this example, you
would specify:
$expectedRecursions = [ ['variants', 'variants'], ]; $recursionChecker = new RecursionChecker(new NullLogger(), $expectedRecursions);
With this configuration, the ClassMetadata found in the property type for the
variants property of the final model will have no field variants, so that
code working on the metadata does not need to worry about infinite recursion.
Extending the metadata parser
This library comes with a couple of parsers, but you can write your own to
handle custom information specific to your project. Use the
PropertyVariationMetadata::setCustomInformation method to add custom data,
and use PropertyMetadata::getCustomInformation to read it in your metadata
consumers.
liip/metadata-parser 适用场景与选型建议
liip/metadata-parser 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 336.02k 次下载、GitHub Stars 达 17, 最近一次更新时间为 2026 年 01 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 liip/metadata-parser 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 liip/metadata-parser 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 336.02k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 17
- 点击次数: 23
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-04