鉴别器映射注释中的环境变量或函数



如何根据当前环境设置鉴别器映射?

我有一个使用单表继承和鉴别器列的实体:

@ORMDiscriminatorMap({1="Product", 2="User"})

鉴别器值(1, 2(在我的生产和开发环境中有所不同,因此需要动态设置这些值。不幸的是,这似乎不是原则注释文档中的选项。

直接在注释中使用环境似乎不起作用。例如,我尝试过:

@ORMDiscriminatorMap('%discrimination_array%')

然后在doctrine.yaml中定义discrimination_array

discrimination_array: '{%env(PRODUCT)%="Product", %env(USER)%="User"}'

以及.env中相应的环境变量:

PRODUCT=1
USER=2

然而,教义抛出的错误,如

将 varchar 值 '%env(PRODUCT(%' 转换为数据类型 smallint 时转换失败。

是否可以根据当前环境设置阶级歧视地图?

这可以通过扩展特定实体的数据映射来完成。解析注释时,Doctrine 会触发一个事件:

读取实体的映射信息时,该信息将填充到 ClassMetadataInfo 实例中。您可以挂钩到此过程并操作实例。

通过订阅此事件,可以在加载实体后设置实体的DiscriminatorMap

下面是一个一般示例。首先,实现订阅者。加载相关实体 (Item::class( 时,添加相关DiscriminatorMap

<?php
namespace AppDoctrineListener;
use AppEntityItem;
use DoctrineCommonEventSubscriber;
use DoctrineORMEventLoadClassMetadataEventArgs;
class LoadClassMetadataSubscriber implements EventSubscriber
{
private $discriminatorMap;
public function __construct( $discriminatorMap)
{
$this->discriminatorMap = $discriminatorMap;
}
public function getSubscribedEvents()
{
return [
Events::loadClassMetadata
];
}
/**
* @param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/**
* @var DoctrineORMMappingClassMetadata $classMetadata
*/
$classMetadata = $eventArgs->getClassMetadata();
if ($classMetadata->name !== Item::class) {
return;
}
$map = [];
foreach ($this->discriminatorMap as $value) {
$partial = explode('=', $value);
$map[$partial[0]] = $partial[1];
}
$classMetadata->setDiscriminatorMap($map);
}
}

由于鉴别器映射是在解析类之后添加的,因此EntityItem不需要DiscriminatorMap注释:

<?php
namespace AppEntity;
use AppMap;
use DoctrineORMMapping as ORM;
/**
* @ORMEntity(...)
* @ORMTable(...)
* @ORMInheritanceType("SINGLE_TABLE")
* @ORMDiscriminatorColumn(name="discr", type="string")
*/
abstract class Item {

应将映射添加到环境中(.env或类似(:

DISCRIMINATOR_MAP=one=AppEntityItemOne,two=AppEntityItemTwo

将订阅者注册到正确的事件 (config/services.yaml(:

services:
...
# Set up the custom subscriber. It'll take the environmental variable as
# an argument, and subscribe to the `loadClassMetadata` event. 
AppDoctrineListenerLoadClassMetadataSubscriber:
public: true
arguments:
- '%env(csv:MAP)%'
tags:
- { name: doctrine.event_listener, event: loadClassMetadata, lazy: true }

相关内容

  • 没有找到相关文章

最新更新