Download the PHP package mark-gerarts/auto-mapper-plus without Composer

On this page you can find all versions of the php package mark-gerarts/auto-mapper-plus. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package auto-mapper-plus

AutoMapper+

An automapper for PHP inspired by .NET's automapper. Transfers data from one object to another, allowing custom mapping operations.

Build Status

Table of Contents

Installation

This library is available on packagist:

If you're using Symfony, check out the AutoMapper+ bundle.

Why?

When you need to transfer data from one object to another, you'll have to write a lot of boilerplate code. For example when using view models, CommandBus commands, working with API responses, etc.

Automapper+ helps you by automatically transferring properties from one object to another, including private ones. By default, properties with the same name will be transferred. This can be overridden as you like.

Example usage

Suppose you have a class Employee and an associated DTO.

The following snippet provides a quick overview on how the mapper can be configured and used:

In depth

Instantiating the AutoMapper

The AutoMapper has to be provided with an AutoMapperConfig, which holds the registered mappings. This can be done in 2 ways:

Passing it to the constructor:

Using the static constructor:

Using the AutoMapper

Once configured, using the AutoMapper is pretty straightforward:

Registering mappings

Mappings are defined using the AutoMapperConfig's registerMapping() method. By default, every mapping has to be explicitly defined before you can use it.

A mapping is defined by providing the source class and the destination class. The most basic definition would be as follows:

This will allow objects of the Employee class to be mapped to EmployeeDto instances. Since no extra configuration is provided, the mapping will only transfer properties with the same name.

Custom callbacks

With the forMember() method, you can specify what should happen for the given property of the destination class. When you pass a callback to this method, the return value will be used to set the property.

The callback receives the source object as argument.

Operations

Behind the scenes, the callback in the previous example is wrapped in a MapFrom operation. Operations represent the action that should be performed for the given property.

The following operations are provided:

Name Explanation
MapFrom Maps the property from the value returned from the provided callback. Gets passed the source object, an instance of the AutoMapper and optionally the current context.
Ignore Ignores the property.
MapTo Maps the property to another class. Allows for nested mappings. Supports both single values and collections.
MapToAnyOf Similar to MapTo, but maps the property to the first match from a list of classes. This can be used for polymorphic properties. Supports both single values and collections.
FromProperty Use this to explicitly state the source property name.
DefaultMappingOperation Simply transfers the property, taking into account the provided naming conventions (if there are any).
SetTo Always sets the property to the given value

You can use them with the same forMember() method. The Operation class can be used for clarity.

MapTo requires some extra explanation. Since lists and maps are the same data structure in PHP (arrays), we can't reliably distinct between the two. MapTo therefore accepts a second parameter, $sourceIsObjectArray, a boolean value that indicates whether the source value should be interpreted as a collection, or as an associative array representing an object. By default we assume a collection or a single non-array value.

You can create your own operations by implementing the MappingOperationInterface. Take a look at the provided implementations for some inspiration.

If you need to have the automapper available in your operation, you can implement the MapperAwareInterface, and use the MapperAwareTrait. The default MapTo and MapFrom operations use these.

Dealing with polymorphic properties

Sometimes you have properties which contain a list of different types of objects e.g. when you load all entities with single table inheritance. You can use MapToAnyOf to map every object to a possible different one. Keep in mind that the mapping for the child class has to be registered as well. The source property can be both a single value or a collection.

Dealing with nested mappings

Nested mappings can be registered using the MapTo operation. Keep in mind that the mapping for the child class has to be registered as well.

MapTo supports both single entities and collections.

Handling object construction

You can specify how the new destination object will be constructed (this isn't relevant if you use mapToObject). You can do this by registering a factory callback. This callback will be passed both the source object and an instance of the AutoMapper.

Another option is to skip the constructor all together. This can be set using the options.

ReverseMap

Since it is a common use case to map in both directions, the reverseMap() method has been provided. This creates a new mapping in the alternate direction.

reverseMap will keep the registered naming conventions into account, if there are any.

Note: reverseMap() simply creates a completely new mapping in the reverse direction, using the default options. However, every operation you defined with forMember that implements the Reversible interface, gets defined for the new mapping as well. Currently, only fromProperty supports being reversed.

To make things more clear, take a look at the following example:

Copying a mapping

When defining different view models, it can occur that you have lots of similar properties. For example, with a ListViewModel and a DetailViewModel. This means that the mapping configuration will be similar as well.

For this reason, it is possible to copy a mapping. In practice this means that all the options will be copied, and all the explicitly defined mapping operations.

After copying the mapping, you're free to override operations or options on the new mapping.

Automatic creation of mappings

When you're dealing with very simple mappings that don't require any configuration, it can be quite cumbersome the register a mapping for each and every mapping. For these cases it is possible to enable the automatic creation of mappings:

With this configuration the mapper will generate a very basic mapping on the fly instead of throwing an exception if the mapping is not configured.

Resolving property names

Unless you define a specific way to fetch a value (e.g. mapFrom), the mapper has to have a way to know which source property to map from. By default, it will try to transfer data between properties of the same name. There are, however, a few ways to alter this behaviour.

If a source property is specifically defined (e.g. FromProperty), this will be used in all cases.

Naming conventions

You can specify the naming conventions followed by the source & destination classes. The mapper will take this into account when resolving names.

For example:

The following conventions are provided (more to come):

You can implement your own by using the NamingConventionInterface.

Explicitly state source property

As mentioned earlier, the operation FromProperty allows you to explicitly state what property of the source object should be used.

You should read the previous snippet as follows: "For the property named 'id' on the destination object, use the value of the 'identifier' property of the source object".

FromProperty is Reversible, meaning that when you apply reverseMap(), AutoMapper will know how to map between the two properties. For more info, read the section about reverseMap.

Resolving names with a callback

Should naming conventions and explicitly stating property names not be sufficient, you can resort to a CallbackNameResolver (or implement your own NameResolverInterface).

This CallbackNameResolver takes a callback as an argument, and will use this to transform property names.

The Options object

The Options object is a value object containing the possible options for both the AutoMapperConfig and the Mapping instances.

The Options you set for the AutoMapperConfig will act as the default options for every Mapping you register. These options can be overridden for every mapping.

For example:

The available options that can be set are:

Name Default value Comments
Source naming convention null The naming convention of the source class (e.g. CamelCaseNamingConversion). Also see naming conventions.
Destination naming convention null See above.
Skip constructor true whether or not the constructor should be skipped when instantiating a new class. Use $options->skipConstructor() and $options->dontSkipConstructor() to change.
Property accessor PropertyAccessor Use this to provide an alternative implementation of the property accessor. A property accessor combines the reading and writing of properties
Property reader PropertyAccessor Use this to provide an alternative implementation of the property reader.
Property writer PropertyAccessor Use this to provide an alternative implementation of the property writer.
Default mapping operation DefaultMappingOperation the default operation used when mapping a property. Also see mapping operations
Default name resolver NameResolver The default class to resolve property names
Custom Mapper null Grants the ability to use a custom mapper.
Object crates [\stdClass::class] See the dedicated section.
Ignore null properties false Sets whether or not a source property should be mapped to the destination object if the source value is null
Use substitution true Whether or not the Liskov substitution principle should be applied when resolving a mapping.
createUnregisteredMappings false Whether or not an exception should be thrown for unregistered mappings, or a mapping should be generated on the fly.

Setting the options

For the AutoMapperConfig

You can set the options for the AutoMapperConfig by retrieving the object:

Alternatively, you can set the options by providing a callback to the constructor. The callback will be passed an instance of the default Options:

For the Mappings

A mapping also has the getOptions method available. However, chainable helper methods exist for more convenient overriding of the options:

Setting options via a callable has been provided for mappings as well, using the setDefaults() method:

Mapping with stdClass

As a side note it is worth mentioning that it is possible to map from and to stdClass. Mapping from stdClass happens as you would expect, copying properties to the new object.

Mapping to \stdClass requires some explanation. All properties available on the provided source object are copied to the \stdClass as public properties. It's still possible to define operations for individual properties (for example, to ignore a property).

Naming conventions will be taken into account, so keep this in mind when defining operations. The property name has to match the naming convention of the target.

The concept of object crates

As suggested and explained in this issue, AutoMapper+ uses object crates to allow mapping to \stdClass. This means you can register your own classes as well to be an object crate. This makes the mapper handle it exactly as \stdClass, writing all source properties to public properties on the target.

Registering object crates can be done using the Options.

Mapping with arrays

It is possible to map associative arrays into objects (shout-out to @slava-v). This can be done just like you would declare a regular mapping:

See the MapTo section under Operations for some more details about the intricacies involving this operation in combination with arrays.

As for now, it is not possible to map to an array. While this is relatively easy to implement, it would introduce a breaking change. It is part of version 2.x, so check there if you need this feature.

Using a custom mapper

This library attempts to make registering mappings painless, with as little configuration as possible. However, cases exist where a mapping requires a lot of custom code. This code would look a lot cleaner if put in its own class. Another reason to resort to a custom mapper would be performance.

It is therefore possible to specify a custom mapper class for a mapping. This mapper has to implement the MapperInterface. For your convenience, a CustomMapper class has been provided that implements this interface.

Adding context

Sometimes a mapping should behave differently based on the context. It is therefore possible to pass a third argument to the map methods to describe the current context. Both the MapFrom and MapTo operations can make use of this context to alter their behaviour.

The context argument is an array that can contain any arbitrary value. Note that this argument isn't part of the AutoMapperInterface yet, since it would break backwards compatibility. It will be added in the next major release.

When using the mapToObject method, the context will contain the destination object by default. It is accessible using $context[AutoMapper::DESTINATION_CONTEXT]. This is useful in scenarios where you need data from the destination object to populate the object you're mapping.

When implementing a custom constructor, the context will contain the destination class by default. It is accessible using $context[AutoMapper::DESTINATION_CLASS_CONTEXT].

When mapping an object graph, the context will also contain arrays for property name paths, ancestor source objects and ancestor destination objects. Those arrays are accessible using $context[AutoMapper::PROPERTY_STACK_CONTEXT], $context[AutoMapper::SOURCE_STACK_CONTEXT] and $context[AutoMapper::DESTINATION_STACK_CONTEXT]. They can be used to implement custom mapping function based on the hierarchy level and current position inside the object graph being mapped.

Misc

Similar libraries

When picking a library, it's important to see what options are available. No library is perfect, and they all have their pro's and con's.

A few other object mappers exist for PHP. They're listed here with a short description, and are definitely worth checking out!

Performance benchmarks (credit goes to idr0id):

Runtime: PHP 7.2.9-1
Host: Linux 4.18.0-2-amd64 #1 SMP Debian 4.18.10-2 (2018-11-02) x86_64
Collection size: 100000

package duration (MS) MEM (B)
native php 32 123736064
mark-gerarts/auto-mapper-plus (custom mapper) 92 123736064
jane-php/automapper (optimized) 100 123736064
jane-php/automapper 136 123736064
idr0id/papper 310 123736064
trismegiste/alkahest 424 113250304
mark-gerarts/auto-mapper-plus 623 123736064
nylle/php-automapper 642 123736064
bcc/auto-mapper-bundle 2874 123736064

Up-to-date benchmarks can be found here.

Note that using a custom mapper is very fast. So when performance really starts to matter in your application, you can easily implement a custom mapper where needed, without needing to change the code that uses the mapper.

See also

A note on PHPStan

Because of an issue described here, PHPStan reports the following error if you use the $context parameter:

If you see this error, you should enable the AutoMapper+ extension. Please note that this is a temporary solution. The issue will be fixed in the 2.0 release.

Roadmap

Version 2 is in the works, check there for new features as well


All versions of auto-mapper-plus with dependencies

PHP Build Version
Package Version
Requires php Version >=7.4.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package mark-gerarts/auto-mapper-plus contains the following files

Loading the files please wait ....