Implementing a TypedFieldMapper

New in version 2.14.

バージョン 2.14 の新機能。

You can specify custom typed field mapping between PHP type and DBAL type using Doctrine\ORM\Configuration and a custom Doctrine\ORM\Mapping\TypedFieldMapper implementation.

Doctrine\ORM\Configuration とカスタム Doctrine\ORM\Mapping\TypedFieldMapper 実装を使用して、PHP 型と DBAL 型の間のカスタムの型付きフィールド マッピングを指定できます。

<?php
$configuration->setTypedFieldMapper(new CustomTypedFieldMapper());

DefaultTypedFieldMapper

By default the Doctrine\ORM\Mapping\DefaultTypedFieldMapper is used, and you can pass an array of PHP type => DBAL type mappings into its constructor to override the default behavior or add new mappings.

デフォルトでは Doctrine\ORM\Mapping\DefaultTypedFieldMapper が使用され、コンストラクターに PHP タイプ => DBAL タイプ マッピングの配列を渡して、デフォルトの動作をオーバーライドしたり、新しいマッピングを追加したりできます。

<?php
use App\CustomIds\CustomIdObject;
use App\DBAL\Type\CustomIdObjectType;
use Doctrine\ORM\Mapping\DefaultTypedFieldMapper;

$configuration->setTypedFieldMapper(new DefaultTypedFieldMapper([
    CustomIdObject::class => CustomIdObjectType::class,
]));

Then, an entity using the CustomIdObject typed field will be correctly assigned its DBAL type (CustomIdObjectType) without the need of explicit declaration.

次に、CustomIdObject 型付きフィールドを使用するエンティティには、明示的な宣言を必要とせずに、その DBAL 型 (CustomIdObjectType) が正しく割り当てられます。

It is perfectly valid to override even the “automatic” mapping rules mentioned above:

上記の「自動」マッピング ルールをオーバーライドすることは完全に有効です。

<?php
use App\DBAL\Type\CustomIntType;
use Doctrine\ORM\Mapping\DefaultTypedFieldMapper;

$configuration->setTypedFieldMapper(new DefaultTypedFieldMapper([
    'int' => CustomIntType::class,
]));

Note

ノート

If chained, once the first TypedFieldMapper assigns a type to a field, the DefaultTypedFieldMapper will ignore its mapping and not override it anymore (if it is later in the chain). See below for chaining type mappers.

チェーンされている場合、最初の TypedFieldMapper がフィールドに型を割り当てると、DefaultTypedFieldMapper はそのマッピングを無視し、それ以上オーバーライドしません (チェーンの後半にある場合)。連鎖型マッパーについては、以下を参照してください。

TypedFieldMapper interface

The interface Doctrine\ORM\Mapping\TypedFieldMapper allows you to implement your own typed field mapping logic. It consists of just one function

インターフェース Doctrine\ORM\Mapping\TypedFieldMapper を使用すると、独自の型付きフィールド マッピング ロジックを実装できます。たった1つの機能で構成されています

<?php
/**
 * Validates & completes the given field mapping based on typed property.
 *
 * @param array{fieldName: string, enumType?: string, type?: mixed}  $mapping The field mapping to validate & complete.
 * @param \ReflectionProperty                                        $field
 *
 * @return array{fieldName: string, enumType?: string, type?: mixed} The updated mapping.
 */
public function validateAndComplete(array $mapping, ReflectionProperty $field): array;

ChainTypedFieldMapper

The class Doctrine\ORM\Mapping\ChainTypedFieldMapper allows you to chain multiple TypedFieldMapper instances. When being evaluated, the TypedFieldMapper::validateAndComplete is called in the order in which the instances were supplied to the ChainTypedFieldMapper constructor.

クラス Doctrine\ORM\Mapping\ChainTypedFieldMapper を使用すると、複数の TypedFieldMapper インスタンスをチェーンできます。評価されると、TypedFieldMapper::validateAndComplete が、インスタンスが ChainTypedFieldMapper コンストラクターに提供された順序で呼び出されます。

<?php
use App\DBAL\Type\CustomIntType;
use Doctrine\ORM\Mapping\ChainTypedFieldMapper;
use Doctrine\ORM\Mapping\DefaultTypedFieldMapper;

$configuration->setTypedFieldMapper(
    new ChainTypedFieldMapper(
        new DefaultTypedFieldMapper(['int' => CustomIntType::class,]),
        new CustomTypedFieldMapper()
    )
);

Implementing a TypedFieldMapper

If you want to assign all BackedEnum fields to your custom BackedEnumDBALType or you want to use different DBAL types based on whether the entity field is nullable or not, you can achieve this by implementing your own typed field mapper.

すべての BackedEnum フィールドをカスタム BackedEnumDBALType に割り当てたい場合、またはエンティティ フィールドが null 可能かどうかに基づいて異なる DBAL タイプを使用したい場合は、独自の型付きフィールド マッパーを実装することでこれを実現できます。

You need to create a class which implements Doctrine\ORM\Mapping\TypedFieldMapper.

Doctrine\ORM\Mapping\TypedFieldMapper を実装するクラスを作成する必要があります。

<?php
final class CustomEnumTypedFieldMapper implements TypedFieldMapper
{
    /**
     * {@inheritdoc}
     */
    public function validateAndComplete(array $mapping, ReflectionProperty $field): array
    {
        $type = $field->getType();

        if (
            ! isset($mapping['type'])
            && ($type instanceof ReflectionNamedType)
        ) {
            if (! $type->isBuiltin() && enum_exists($type->getName())) {
                $mapping['type'] = BackedEnumDBALType::class;
            }
        }

        return $mapping;
    }
}

Note

ノート

Note that this case checks whether the mapping is already assigned, and if yes, it skips it. This is up to your implementation. You can make a “greedy” mapper which will always override the mapping with its own type, or one that behaves like the DefaultTypedFieldMapper and does not modify the type once its set prior in the chain.

この場合、マッピングがすでに割り当てられているかどうかを確認し、割り当てられている場合はスキップすることに注意してください。これは実装次第です。独自のタイプでマッピングを常にオーバーライドする「貪欲な」マッパーを作成するか、DefaultTypedFieldMapper のように動作し、チェーンの前に設定されたタイプを変更しないマッパーを作成できます。

Table Of Contents

This Page

Fork me on GitHub