retailcrm / auto-mapper-bundle
为Symfony的对象到对象映射包
Requires
- php: >=8.1
- doctrine/common: ^2.0||^3.0
- doctrine/orm: ^2.0||^3.0
- symfony/expression-language: ^5.4||^6.0||^7.0
- symfony/framework-bundle: ^5.4||^6.0||^7.0
- symfony/property-access: ^5.4||^6.0||^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.56
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.0
- retailcrm/php-code-style: ^1.0
This package is auto-updated.
Last update: 2024-08-26 14:46:28 UTC
README
github.com/retailcrm/AutoMapperBundle
是 github.com/michelsalib/BCCAutoMapperBundle
的分支
安装和配置
获取包
composer install retailcrm/auto-mapper-bundle
将 AutoMapperBundle 添加到您的应用程序内核
<?php // app/AppKernel.php public function registerBundles() { return array( // ... new Retailcrm\AutoMapperBundle\AutoMapperBundle(), // ... ); }
使用示例
提供一个源对象和一个目标对象
<?php namespace My; class SourcePost { public $name; public $description; /** * @var SourceAuthor */ public $author; } class SourceAuthor { public $name; } class DestinationPost { public $title; public $description; public $author; }
使用默认映射
默认映射将自动关联具有相同名称的成员。它将自动使用公共属性或查找getter。
您可以通过这种方式创建默认映射并映射对象
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost'); // create objects $source = new SourcePost(); $source->description = 'Symfony2 developer'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->description; // outputs 'Symfony2 developer'
路由成员
在上一个示例中,字段 name
和 title
不匹配。您可以通过这种方式路由成员
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and route members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->route('title', 'name'); // create objects $source = new SourcePost(); $source->name = 'AutoMapper Bundle'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->title; // outputs 'AutoMapper Bundle'
请注意,如果 title
或 name
是私有的,它将尝试使用getter和setter来路由成员。
通过闭包映射成员
如果您在映射成员时需要额外的计算,您可以提供一个闭包来处理特定的成员
<?php use Retailcrm\AutoMapperBundle\Mapper\FieldAccessor\Closure; // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and override members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->forMember('title', new Closure(function(SourcePost $source){ return \strtoupper($source->name); })); // create objects $source = new SourcePost(); $source->name = 'AutoMapper Bundle'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->title; // outputs 'AUTOMAPPER BUNDLE'
映射一个图
您可以这样映射作者->name成员
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and override members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->route('author', 'author.name'); // create objects $source = new SourcePost(); $source->author = new SourceAuthor(); $source->author->name = 'Michel'; $destination = new DestinationPost(); $mapper = new Mapper(); // map $mapper->map($source, $destination); echo $destination->author; // outputs 'Michel'
请注意,如果有私有成员,它将尝试使用getter和setter来路由成员。
使用Symfony表达式语言
如果您想定义属性如何访问,请使用 Expression 字段访问器:您可以阅读有关 ExpressionLanguage 的所有文档。
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and override members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->forMember('author', new Expression('author.getFullName()')); // create objects $source = new SourcePost(); $source->author = new SourceAuthor(); $source->author->name = 'Michel'; $destination = new DestinationPost(); $mapper = new Mapper(); // map $mapper->map($source, $destination); echo destination->author; // outputs 'Michel'
映射到常量
您可以映射特定成员到常量
<?php use Retailcrm\AutoMapperBundle\Mapper\FieldAccessor\Constant; // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and override members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->forMember('title', new Constant('Constant title')); // create objects $source = new SourcePost(); $source->name = 'AutoMapper Bundle'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->title; // outputs 'Constant title'
深度对象映射
您可以映射特定成员到常量
<?php use Retailcrm\AutoMapperBundle\Mapper\FieldAccessor\Constant; // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost'); // Set property deep mapping $mapper->filter('author', new ObjectMappingFilter('My\DestinationAuthor')); // create objects $source = new SourcePost(); $source->author = new SourceAuthor(); $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo get_class(destination->author); // outputs 'My\DestinationAuthor'
深度数组对象映射
您可以映射特定成员到常量
<?php use Retailcrm\AutoMapperBundle\Mapper\FieldAccessor\Constant; // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost'); // Set property deep mapping $mapper->filter('comments', new ArrayObjectMappingFilter('My\DestinationComment')); // create objects $source = new SourcePost(); $source->comments = array( new SourceComment(), new SourceComment(), ); $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo get_class(destination->comments[0]); // outputs 'My\DestinationComment'
应用过滤器
您可以对映射成员应用过滤器。目前只有一个 IfNull
过滤器,如果字段无法映射或映射到null值,则应用默认值
<?php use Retailcrm\AutoMapperBundle\Mapper\FieldAccessor\IfNull; // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map and override members $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->filter('title', new IfNull('Default title')); // create objects $source = new SourcePost(); $source->name = 'AutoMapper Bundle'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->title; // outputs 'Default title'
注册映射
您可以在容器级别定义映射并将其添加到Mapper。
扩展 Retailcrm\AutoMapperBundle\Mapper\AbstractMap
类
<?php namespace My; use Retailcrm\AutoMapperBundle\Mapper\AbstractMap; class PostMap extends AbstractMap { function __construct() { $this->buildDefaultMap(); // generate the default map $this->route('title', 'name'); // override the title member } public function getDestinationType() { return 'My\DestinationPost'; } public function getSourceType() { return 'My\SourcePost'; } }
您可以使用 auto_mapper.map
标签注册所有实现 MapInterface
的映射
// services.yml _instanceof: Retailcrm\AutoMapperBundle\Mapper\MapInterface: tags: ['auto_mapper.map']
现在您可以直接使用映射器
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create objects $source = new SourcePost(); $source->name = 'AutoMapper Bundle'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); echo $destination->title; // outputs 'AutoMapper Bundle'
忽略字段
您可以忽略目标字段。
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->ignoreMember('description'); // create objects $source = new SourcePost(); $source->description = 'Symfony2 developer'; $destination = new DestinationPost(); // map $mapper->map($source, $destination); var_dump($destination->description); // ignored, will be null
不要覆盖已设置的字段
您可以设置映射器不覆盖目标上已设置的字段。
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->setOverwriteIfSet(false); // create objects $source = new SourcePost(); $source->description = 'Symfony2 developer'; $destination = new DestinationPost(); $destination->description = 'Foo bar'; // map $mapper->map($source, $destination); var_dump($destination->description); // will be 'Foo bar'
跳过null
您可以跳过一个null字段。
<?php // get mapper $mapper = $container->get('auto_mapper.mapper'); // create default map $mapper->createMap('My\SourcePost', 'My\DestinationPost') ->setSkipNull(true); // create objects $source = new SourcePost(); $source->description = null; $destination = new DestinationPost(); $destination->description = 'Foo bar'; // map $mapper->map($source, $destination); var_dump($destination->description); // will be 'Foo bar'