cmath10/mapper
Composer 安装命令:
composer require cmath10/mapper
包简介
Mapping library
关键字:
README 文档
README
The library provides a utility for converting objects to each other (and arrays to objects) and transferring data between them by reusable map.
Basic example:
class ArticleInput { public $title; public $text; public $author; } class Article { public $title; public $text; public $author; public function __construct(?string $title = null) { $this->title = $title; } } $input = new ArticleInput(); $input->title = 'title'; $input->text = 'text'; $article1 = new Article(); $mapper = new cmath10\Mapper\Mapper(); $mapper->create(ArticleInput::class, Article::class); $mapper->map($input, $article1); // ($article1->title === 'title') === true // ($article1->text === 'text') === true $article2 = $mapper->map($input, Article::class) // ($article2 instanceof Article) === true // ($article2->title === 'title') === true // ($article2->text === 'text') === true
How it works
The main term of the library is a map. It is an object which is containing information about how to extract values from the source and inject them into a destination object. Values can be processed before injection (to get an opportunity for sanitization and nested mapping).
Map includes:
- field accessors — objects are responsible for value extraction; by default, it is used
symfony/property-accessfor that purpose, but there are other options, like using callbacks orsymfony/expression-languageand presets (if the extracted value is null), also there is an interface for custom accessors; - field filters — objects are responsible for value processing; by default, there are no filters for extracted value; you can use callbacks and mapping filters for nested mapping.
By default, a map creates a set of accessors based on a class properties list, so a field from a source will be mapped on a field of a destination with the same name. You can change this behavior for specific fields if needed.
All maps must be registered in a mapper instance before using. When you call the mapper method map it
seeks the correct map for a given source and destination, then it uses accessors to extract values, filters to process
them, and, after that, injects values to a destination. If the destination is a class name, the mapper will try to
create an instance of the given class, if the class constructor is public and all possible arguments are optional.
Installation
composer require cmath10/mapper
API
cmath10\Mapper\MapperInterface — interface for mappers:
create(string $sourceType, string $destinationType)— creates, registers and returns default map for two classes;register(MapInterface $map)— registers a custom map in the mapper;map($source, $destination)— performs mapping from a source to a destination object or class.
cmath10\mapper\MapInterface — interface for maps:
getSourceType()— returns name of source type; used to find the correct map;getDestinationType()— returns name of destination type; used to find the correct map;getFieldAccessors()— returns all fields accessors;getFieldFilters()— returns all fields filters;getOverwriteIfSet()— returns boolean flag; if true, destination member will be overwritten even if its value is not null;getSkipNull()— returns boolean flag; if true, the mapper will not push null source member's value;route(string $destinationMember, string $sourceMember)— sets mapping of destination route to source route; fluent;forMember(string $destinationMember, AccessorInterface $fieldMapper)— sets custom accessor for field; fluent;filter(string $destinationMember, FilterInterface $fieldFilter)— sets a custom filter for value processing; fluent;ignoreMember(string $destinationMember)— excludes members from accounting, so they will not be filled; fluent.
cmath10\mapper\FieldAccessor\AccessorInterface — interface for accessors:
getValue($source)— extracts value from a source.
cmath10\mapper\FieldFilter\FitlerInterface — interface for filters:
filter($value)— processes the value.
cmath10\Mapper\TypeFilterInterface — interface for type filters is used to process type names. Useful for
extracting class names from runtime generated classes like proxies in Doctrine. Used in default mapper which uses an
array of type filters as a constructor parameter (to instantiate cmath10\mapper\TypeGuesser which is used to
determine the correct map for supplied types in mapper's map method).
Available maps
AbstractMap
Basic class is used to create custom map classes, implements MapperInterface;
provides following protected method:
setupDefaults— creates a set of accessors based on a class properties list.
Usage example:
use cmath10\Mapper\AbstractMap; class ArticleOutputMap extends AbstractMap { public function __construct() { $this ->setupDefaults() // create default accessors set ->route('textNotMappedByDefault', 'text') // customize ; } public function getSourceType(): string { return Article::class; } public function getDestinationType(): string { return ArticleOutput::class; } }
DefaultMap
Simple descendant of AbstractMap, just calls setupDefaults in
its constructor; the mapper create method creates, registers and returns instance of this class.
Available accessors
ClosureAccessor
Uses callback to extract a value:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldAccessor\ClosureAccessor; $mapper = new Mapper(); $mapper ->create(Fixtures\Article::class, Fixtures\ArticleInput::class) ->forMember('author', new ClosureAccessor(fn (Fixtures\ArticleInput $a) => $a->author->name)) ;
ExpressionAccessor
Uses symfony/expression-language to extract a value:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldAccessor\ExpressionAccessor; $mapper = new Mapper(); $mapper ->create(Fixtures\MagazineWithPrivateProperties::class, Fixtures\MagazineOutput::class) ->forMember('articles', new ExpressionAccessor('getArticles()')) ;
PresetAccessor
Does not extract a value, just provides:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldAccessor\PresetAccessor; $mapper = new Mapper(); $mapper ->create(Fixtures\MagazineWithPrivateProperties::class, Fixtures\MagazineOutput::class) ->forMember('articles', new PresetAccessor([])) ;
PropertyPathAccessor
Uses symfony/property-access to extract a value. This accessor is used by default. Calls like:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldAccessor\PropertyPathAccessor; $mapper = new Mapper(); $mapper ->create(Fixtures\MagazineWithPrivateProperties::class, Fixtures\MagazineOutput::class) ->forMember('articles', new PropertyPathAccessor('someFieldWithArticles')) ;
and
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldAccessor\PropertyPathAccessor; $mapper = new Mapper(); $mapper ->create(Fixtures\MagazineWithPrivateProperties::class, Fixtures\MagazineOutput::class) ->route('articles', 'someFieldWithArticles') ;
are equivalent. Also, if the fields in a source and destination have the same name, and you use
setupDefaults, you don't need to call route or forMember explicitly.
Available filters
ClosureFilter
Uses callback to process value:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldFilter\ClosureFilter; // For ArticleInput title='title' we will get Article title='[[title]]' $mapper = new Mapper(); $mapper ->create(Fixtures\ArticleInput::class, Fixtures\Article::class) ->filter('title', new ClosureFilter(static fn ($title) => '[[' . $title . ']]')) ;
IfNullFilter
Replaces the value if it is null:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldFilter\IfNullFilter; // For ArticleInput title=null we will get Article title='defaultTitle' $mapper = new Mapper(); $mapper ->create(Fixtures\ArticleInput::class, Fixtures\Article::class) ->filter('title', new IfNullFilter('defaultTitle')) ;
AbstractMappingFilter
Basic class for filters that can use mapper. Requires class name in the constructor. Used for nested mapping.
ObjectMappingFilter
Descendant of AbstractMappingFilter, uses class name and mapper to make an
object from a source member:
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldFilter\ObjectMappingFilter; $mapper = new Mapper(); $mapper->create(Fixtures\AuthorInput::class, Fixtures\Author::class); $mapper ->create(Fixtures\ArticleInput::class, Fixtures\Article::class) ->route('author', 'author') ->filter('author', new ObjectMappingFilter(Fixtures\Author::class)) ;
ObjectArrayMappingFilter
Descendant of AbstractMappingFilter, uses class name and mapper to make an
array of objects from a source member, if the source member's value is array (returns
an empty array instead):
use cmath10\Mapper\Mapper; use cmath10\Mapper\FieldFilter\ObjectArrayMappingFilter; $mapper = new Mapper(); $mapper->create(Fixtures\Article::class, Fixtures\ArticleOutput::class); $mapper ->create(Fixtures\Magazine::class, Fixtures\MagazineOutput::class) ->route('articles', 'articles') ->filter('articles', new ObjectArrayMappingFilter(Fixtures\ArticleOutput::class)) ;
cmath10/mapper 适用场景与选型建议
cmath10/mapper 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 15 次下载、GitHub Stars 达 0, 最近一次更新时间为 2021 年 04 月 16 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「mapper」 「automapper」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 cmath10/mapper 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 cmath10/mapper 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 cmath10/mapper 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
An object to object mapper bundle for Symfony2
data-mapper php library
PHP port of the popular automapper.org library
Papper is PHP convention-based object to object mapper
Convention-based Alternative ORM
Laravel wrapper for automapper-plus by Mark Gerarts
统计信息
- 总下载量: 15
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2021-04-16