popo / generator
Plain Old PHP Object (POPO) / 数据结构 / 数据传输对象 (DTO) 生成器。将 YAML 架构转换为 PHP 类。
Requires
- php: ^8
- ext-ctype: *
- nette/php-generator: ^4
- symfony/config: ^5|^6
- symfony/console: ^5|^6
- symfony/dependency-injection: ^5|^6
- symfony/finder: ^5|^6
- symfony/yaml: ^5|^6
Requires (Dev)
- bvanhoekelen/performance: ^2.5
- everon/coding-standard: ^3.0
- phpmd/phpmd: ^2.13
- phpstan/phpstan: ^1.4
- phpunit/phpunit: ^10
- squizlabs/php_codesniffer: ^3.7
- symfony/var-dumper: ^5|^6
- dev-main
- 6.5.0
- 6.4.5
- 6.4.4
- 6.4.3
- 6.4.2
- 6.4.1
- 6.4.0
- 6.3.8
- 6.3.7
- 6.3.6
- 6.3.5
- 6.3.4
- 6.3.3
- 6.3.2
- 6.3.1
- 6.3.0
- 6.2.2
- 6.2.1
- 6.2.0
- 6.1.2
- 6.1.1
- 6.1.0
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 6.0.0
- 5.10.1
- 5.9.6
- 5.9.5
- 5.9.4
- 5.9.3
- 5.9.2
- 5.9.1
- 5.9.0
- 5.8.0
- 5.7.0
- 5.6.0
- 5.5.0
- 5.4.0
- 5.3.1
- 5.3.0
- 5.2.2
- 5.2.1
- 5.2.0
- 5.1.2
- 5.1.1
- 5.1.0
- 5.0.2
- 5.0.1
- 5.0.0
- 4.0.0
- 3.1.0
- 3.0.1
- 3.0.0
- 2.6.3
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.1
- 2.5.0
- 2.4.1
- 2.4.0
- 2.3.0
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.0
- 2.0.0
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- dev-feature-key-mapping
- dev-php74
- dev-cleanups
- dev-yaml-support-5.0
This package is auto-updated.
Last update: 2024-09-03 17:33:54 UTC
README
POPO - "Plain Old Php Object" 是受 "Plain Old Java Object" (POJO) 概念启发的。
POPO 生成器还可以定位、加载、验证和合并架构以创建 PHP 源代码文件,代表数组/数据结构/数据传输对象/Doctrine ORM 实体/MongoDB ODM 文档。
POPO 架构可以在多个级别上定义和扩展,并且可以定义在多个文件中。
示例
单个架构文件
简单的 YAML 格式架构,描述 POPO 对象的属性和关系。
#example.popo.yml $: config: namespace: App\Example\Readme outputPath: tests/ Example: Foo: property: [ {name: title} {name: bar, type: popo, default: Bar::class} ] Bar: property: [ {name: title} ]
多个架构文件
相同的示例可以拆分为多个文件。但是这次,是 Bar
修改了 Foo
的定义。
#foo.popo.yml Example: Foo: property: [ {name: title} ]
#bar.popo.yml Example: Foo: property: [ {name: bar, type: popo, default: Bar::class} ] Bar: property: [ {name: title} ]
生成的代码相同,但架构依赖项已反转。
在两种情况下,Foo
对象都使用 Bar
对象作为其依赖项,并且它们都定义在 Example
架构名称下。
生成的代码使用示例
从数组实例化数据结构。
use App\Example\Readme\Foo; $data = [ 'title' => 'A title', 'bar' => [ 'title' => 'Bar lorem ipsum', ], ]; $foo = (new Foo)->fromArray($data); echo $foo->getTitle(); echo $foo->requireBar()->getTitle();
输出
A title
Bar lorem ipsum
显示对象的层次结构作为数组。
use App\Example\Readme\Foo; $foo = (new Foo); $foo->requireBar()->setTitle('new value'); print_r($foo->toArray());
输出
[
'title' => null,
'bar' => [
'title' => 'new value',
],
];
运行 bin/popo generate -s tests/fixtures/popo-readme.yml
或 docker-popo generate -s tests/fixtures/popo-readme.yml
以生成此示例的文件。
安装
composer require popo/generator --dev
注意:当使用 docker 时,可以跳过安装,请参阅 Docker 支持部分。
用法
您可以使用它作为 composer 依赖项或作为 docker 命令。
-
定义架构文件,请参阅 tests/fixtures 以获取示例。
-
生成 POPO 文件,运行
-
使用 composer
vendor/bin/popo generate -s <schema-path> -o <output-path>
-
使用 docker
docker-popo generate -s <schema-path> -o <output-path>
-
例如: bin/popo generate -s tests/fixtures/popo.yml
或 docker-popo generate -s tests/fixtures/popo.yml
。
POPO 架构
POPO 架构可以在多个级别上定义和扩展,并且可以定义在多个文件中。
该架构支持键映射、继承、集合和其他 POPO 对象的封装。
架构定义
$: # file-config, shared configuration for all POPO objects in current schema file config: namespace: string outputPath: string namespaceRoot: string|null # if set remaps namespace and outputPath extend: string|null # which class POPO objects should extend from implement: string|null # which interface POPO objects should implement comment: string|null # Class docblock comment phpComment: string|null # Generated PHP File docblock comment use: array<string>|[] # Import block in generated PHP class trait: array<string>|[] # Traits to be used with generated class attribute: string|null # Class attributes as string attributes: array<key, value>|[] # Class attributes as key value pairs classPluginCollection: array<string>|[] phpFilePluginCollection: array<string>|[] namespacePluginCollection: array<string>|[] propertyPluginCollection: array<string>|[] mappingPolicyPluginCollection: array<string>|[] default: array # default values property: array # shared properties SchemaName: # schema-config $: # shared configuration for all POPO objects in SchemaName, in all schema files config: namespace: string outputPath: string namespaceRoot: string|null extend: string|null implement: string|null comment: string|null phpComment: string|null use: array<string>|[] trait: array<string>|[] attribute: string|null, attributes: array<key, value>|[] classPluginCollection: array<string>|[] phpFilePluginCollection: array<string>|[] namespacePluginCollection: array<string>|[] propertyPluginCollection: array<string>|[] mappingPolicyPluginCollection: array<string>|[] default: array property: [{ name: string, type: type: string default: string supportedTypes: ['array','bool','float','int','string','mixed','const','popo', 'datetime'], comment: string|null, default: mixed, itemType: string|null, itemName: string|null, extra: {timezone: ..., format: ...}, attribute: string|null, attributes: array<key, value>|[] mappingPolicy: ['none', 'lower', 'upper', 'camel-to-snake', 'snake-to-camel'], mappingPolicyValue: string|null }] PopoName: # popo-config config: namespace: string outputPath: string namespaceRoot: string|null extend: string|null implement: string|null comment: string|null phpComment: string|null use: array<string>|[] trait: array<string>|[] attribute: string|null, attributes: array<key, value>|[] classPluginCollection: array<string>|[] phpFilePluginCollection: array<string>|[] namespacePluginCollection: array<string>|[] propertyPluginCollection: array<string>|[] mappingPolicyPluginCollection: array<string>|[] default: array property: [{ name: string, type: type: string default: string supportedTypes: ['array','bool','float','int','string','mixed','const','popo', 'datetime'], comment: string|null, default: mixed, itemType: string|null, itemName: string|null, extra: {timezone: ..., format: ...}, attribute: string|null, attributes: array<key, value>|[] mappingPolicy: ['none', 'lower', 'upper', 'camel-to-snake', 'snake-to-camel'], mappingPolicyValue: string|null }]
架构配置选项
namespace
定义生成的类命名空间。
config: namespace: App\Example ...
outputPath
定义输出目录。
config: outputPath: src/ ...
namespaceRoot
定义应从 outputPath
中删除的起始位置。例如,要生成位于 src/Example
下的文件,使用 App\Example
命名空间。
config: namespace: App\Example outputPath: src/ namespaceRoot: App\ ...
extend
生成的类应从哪个类扩展。必须以 \ 开头或包含 ::class
。
config: extend: \App\Example\AbstractDto::class ...
implement
生成的类应实现哪个接口。必须以 \ 开头或包含 ::class
。
config: implement: \App\Example\DtoInterface::class ...
comment
类注释。
config: comment: | @Document(collection="events") ...
phpComment
生成的 PHP 文件注释。
config: phpComment: | Auto generated. @SuppressWarnings(PHPMD) @phpcs:ignoreFile ...
use
导入语句。
config: use: - Doctrine\ODM\MongoDB\Mapping\Annotations\Document - Doctrine\ODM\MongoDB\Mapping\Annotations\Field - Doctrine\ODM\MongoDB\Mapping\Annotations\Id ...
trait
特质语句。
config: trait: - App\Example\MyTrait ...
attribute
类属性值。
config: attribute: | #[Doctrine\ORM\Mapping\Entity(repositoryClass: LogEventRepository::class)] ...
attributes
: array
属性值作为集合。支持值
name
value
:mixed
config: attributes: - name: Doctrine\ORM\Mapping\Entity value: {repositoryClass: LogEventRepository::class} ...
classPluginCollection
: array
用于生成方法的附加插件。
config: classPluginCollection: - \App\Plugin\ExampleMethodPopoPlugin::class ...
namespacePluginCollection
: array
用于生成命名空间块的附加插件。
config: namespacePluginCollection: - \App\Plugin\ExampleNamespacePopoPlugin::class ...
propertyPluginCollection
: array
用于生成属性的附加插件。
config: propertyPluginCollection: - \App\Plugin\ExamplePropertyPopoPlugin::class ...
mappingPolicyPluginCollection
: 数组
用于映射属性名称的插件集合,例如 fooId
=> FOO_ID
。
config: mappingPolicyPluginCollection: - \App\Plugin\SpecialCaseMappingPopoPlugin::class ...
属性配置选项
name
属性的名称。相关方法将基于此值生成。例如 getFooBar()
。这是一个必需参数。
property: - name: title ...
类型
属性数据类型,支持的类型有
数组
布尔型
浮点型
整型
字符串
混合型
常量
popo
日期时间
默认属性类型是 字符串
。
property: - name: precision type: float ...
comment
属性和方法的 Docblock 值。
property: - name: title comment: Lorem ipsum ...
默认: 混合型
默认值。
property: - name: items default: \App\ExampleInterface::TEST_BUZZ ...
额外: 数组
用于 日期时间
数据类型。支持的值
格式
时区
property: - name: created type: datetime extra: timezone: Europe/Paris format: D, d M y H:i:s O ...
itemType
用于 数组
数据类型,与 itemName
元素一起。描述单个数组元素的类型。
property: - name: products type: array itemType: Product::class ...
itemName
用于 数组
数据类型。描述单个数组元素的名称。例如:setProducts(array $products)
,addProduct(Product $item)
。
property: - name: products type: array itemName: product ...
attribute
属性值。
property: - name: price attribute: | #[Doctrine\ORM\Mapping\Column(type: Types::INTEGER)] ...
attributes
: array
属性值作为集合。支持值
name
value
:mixed
property: - name: id attributes: - name: Doctrine\ORM\Mapping\Column value: ['length: 255'] ...
mappingPolicy: 数组
动态重映射属性名称,例如,fooId
=> FOO_ID
。支持的值
无
小写
大写
驼峰转蛇形
蛇形转驼峰
property: - name: fooId mappingPolicy: - camel-to-snake - upper ...
mappingPolicyValue
静态重映射属性名称,例如,fooId
=> FOO_ID
。
property: - name: fooId mappingPolicyValue: FOO_ID ...
Schema 继承
popo-config
的值覆盖 schema-file-config
的值,而 schema-file-config
的值覆盖 schema-config
的值。
此外,还有一个在设置 --schemaConfigFilename
参数时定义的 global-config
。
schema-config
配置被定义为 Schema
属性。它将在给定 schema 下的所有文件中的所有 POPO 对象中使用。
schema-file-config
配置被定义为 SchemaFile
属性。它将在当前文件中的所有 POPO 对象中使用。
popo-config
配置被定义为 POPO
属性。它将在当前文件中的一个特定 POPO 对象中使用。
有关 schema 示例,请参阅 tests/fixtures。
属性名称重映射
POPO 可以重映射属性键名,例如将 foo_id
改为 fooId
。
请参阅 属性名称重映射 文档。
插件架构
可以通过命令行或配置提供新功能。
请参阅 插件 文档。
Doctrine 支持
请参阅 Doctrine 支持 文档。
命令行选项
请参阅 命令行选项 文档。
更多示例
请参阅 fixtures 和 tests 以获取更多使用示例。
Composer 脚本
将 popo 脚本添加到 composer 中,并在项目中运行 composer popo
。
"scripts": {
"popo": [
"bin/popo generate -s <schema-path>"
]
},
"scripts-descriptions": {
"popo": "Generate POPO files"
}
Docker 支持
使用 docker,您可以在项目中不安装 POPO
依赖项的情况下生成文件。
docker container run -it --rm oliwierptak/popo /app/bin/popo
您可以直接运行命令,也可以创建别名,例如。
alias docker-popo='docker container run -it --rm oliwierptak/popo /app/bin/popo ${@}'
例如
docker-popo generate -s tests/fixtures/popo.yml
docker-popo report -s tests/fixtures/popo.yml
另请参阅: bin/docker-popo。
PHP 版本兼容性
- POPO
v1.x
- PHP 7.2+ - POPO
v2.x
- PHP 7.2+ - POPO
v3.x
- PHP 7.4+ - POPO
v4.x
- PHP 7.4+ - POPO
v5.x
- PHP 7.4+ - POPO
v6.x
- PHP 8+
POPO schema 示例
生成 PopoConfigurator 类的示例模式。
$: config: namespace: Popo outputPath: src/ phpComment: | @SuppressWarnings(PHPMD) @phpcs:ignoreFile Popo: PopoConfigurator: default: phpFilePluginCollection: - \Popo\Plugin\PhpFilePlugin\StrictTypesPhpFilePlugin::class - \Popo\Plugin\PhpFilePlugin\CommentPhpFilePlugin::class namespacePluginCollection: - \Popo\Plugin\NamespacePlugin\UseStatementPlugin::class classPluginCollection: - \Popo\Plugin\ClassPlugin\ClassAttributePlugin::class - \Popo\Plugin\ClassPlugin\ClassCommentPlugin::class - \Popo\Plugin\ClassPlugin\ConstPropertyClassPlugin::class - \Popo\Plugin\ClassPlugin\DateTimeMethodClassPlugin::class - \Popo\Plugin\ClassPlugin\ExtendClassPlugin::class - \Popo\Plugin\ClassPlugin\ImplementClassPlugin::class - \Popo\Plugin\ClassPlugin\IsNewClassPlugin::class - \Popo\Plugin\ClassPlugin\ListModifiedPropertiesClassPlugin::class - \Popo\Plugin\ClassPlugin\MetadataClassPlugin::class - \Popo\Plugin\ClassPlugin\ModifiedToArrayClassPlugin::class - \Popo\Plugin\ClassPlugin\PopoMethodClassPlugin::class - \Popo\Plugin\ClassPlugin\RequireAllClassPlugin::class - \Popo\Plugin\ClassPlugin\UpdateMapClassPlugin::class - \Popo\Plugin\ClassPlugin\FromArrayClassPlugin::class - \Popo\Plugin\ClassPlugin\FromMappedArrayClassPlugin::class - \Popo\Plugin\ClassPlugin\ToArrayClassPlugin::class - \Popo\Plugin\ClassPlugin\ToMappedArrayClassPlugin::class - \Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayLowercasePlugin::class - \Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayUppercasePlugin::class - \Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArraySnakeToCamelPlugin::class - \Popo\Plugin\ClassPlugin\MappingPolicyMethod\ToArrayCamelToSnakePlugin::class propertyPluginCollection: - \Popo\Plugin\PropertyPlugin\AddItemPropertyMethodPlugin::class - \Popo\Plugin\PropertyPlugin\DefinePropertyPlugin::class - \Popo\Plugin\PropertyPlugin\GetPropertyMethodPlugin::class - \Popo\Plugin\PropertyPlugin\HasPropertyMethodPlugin::class - \Popo\Plugin\PropertyPlugin\RequirePropertyMethodPlugin::class - \Popo\Plugin\PropertyPlugin\SetPropertyMethodPlugin::class mappingPolicyPluginCollection: none: \Popo\Plugin\MappingPolicy\NoneMappingPolicyPlugin::class lower: \Popo\Plugin\MappingPolicy\LowerMappingPolicyPlugin::class upper: \Popo\Plugin\MappingPolicy\UpperMappingPolicyPlugin::class snake-to-camel: \Popo\Plugin\MappingPolicy\SnakeToCamelMappingPolicyPlugin::class camel-to-snake: \Popo\Plugin\MappingPolicy\CamelToSnakeMappingPolicyPlugin::class property: [ {name: schemaPath} {name: namespace} {name: namespaceRoot} {name: outputPath} {name: phpFilePluginCollection, type: array, itemType: string, itemName: phpFilePluginClass} {name: namespacePluginCollection, type: array, itemType: string, itemName: namespacePluginClass} {name: classPluginCollection, type: array, itemType: string, itemName: classPluginClass} {name: propertyPluginCollection, type: array, itemType: string, itemName: propertyPluginClass} {name: mappingPolicyPluginCollection, type: array, itemType: string, itemName: mappingPolicyPluginClass} {name: schemaConfigFilename} {name: schemaPathFilter} {name: schemaFilenameMask, default: '*.popo.yml'} {name: shouldIgnoreNonExistingSchemaFolder, type: bool} ]}}