我在条令文档中发现了以下例子,他们在其中添加了对特征的映射:
/**
* Trait class
*/
trait ExampleTrait
{
/** @Id @Column(type="string") */
private $id;
/**
* @Column(name="trait_foo", type="integer", length=100, nullable=true, unique=true)
*/
protected $foo;
/**
* @OneToOne(targetEntity="Bar", cascade={"persist", "merge"})
* @JoinColumn(name="example_trait_bar_id", referencedColumnName="id")
*/
protected $bar;
}
我正在尝试映射一个trait,而不必在继承它的类中复制映射。我没有诚实地尝试过上面的方法,因为我的当前项目正在使用yaml进行映射,但看起来普通php类在使用trait时也会继承映射。
有没有一种方法可以继承这个特性的映射,而不使用关联,而是使用yaml或xml?我尝试将特性设置为映射的超类,但没有成功,但我基本上在寻找相同类型的想法。
谢谢。
我发现实现映射特征的唯一方法是使用订阅者。以下应该适用于您的示例,并且它很容易自定义:
<?php
namespace App'EventSubscriber'Doctrine;
use App'Model'Bar;
use App'Model'ExampleTrait;
use Doctrine'Common'EventSubscriber;
use Doctrine'DBAL'Types'Types;
use Doctrine'ORM'Event'LoadClassMetadataEventArgs;
use Doctrine'ORM'Events;
use Doctrine'ORM'Mapping'ClassMetadataInfo;
final class ResolveTraitSubscriber implements EventSubscriber
{
public function getSubscribedEvents(): array
{
return [
Events::loadClassMetadata,
];
}
public function loadClassMetadata(LoadClassMetadataEventArgs $args): void
{
$methods = [
ExampleTrait::class => [$this, 'addExampleTrait'],
// add more traits if needed...
];
$metadata = $args->getClassMetadata();
$traits = (array) $metadata->reflClass?->getTraits();
foreach ($traits as $trait) {
$name = $trait->getName();
if (isset($methods[$name])) {
$methods[$name]($metadata);
}
}
}
private function addExampleTrait(ClassMetadataInfo $metadata): void
{
$metadata->mapField([
'fieldName' => 'id',
]);
$metadata->mapField([
'fieldName' => 'trait_foo',
'length' => 100,
'nullable' => true,
'unique' => true,
]);
$metadata->mapOneToOne([
'targetEntity' => Bar::class,
'cascade' => ['persist', 'merge'],
]);
}
}
不要忘记将它定义为一个带有doctrine.event_subscriber
标签的服务。
用YAML:声明mappedSupperClass
Namespace'For'Your'MappingClass:
type: mappedSuperclass
fields:
id:
id:
type: integer
generator:
strategy: AUTO
... other fields and relations
用XML:声明
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="Namespace'For'Your'MappingClass">
<field name="foo" column="foo" type="string" length="255" />
<field name="bar" column="bar" type="string" length="255" unique="true" />
... other fields
</mapped-superclass>
</doctrine-mapping>
如果运行app/console doctrine:generate:entities
,您将能够在其他实体中使用mappedSuperClass作为优势。