Php 如何在Symfony2表单类型中使用已解析的目标实体?

Php 如何在Symfony2表单类型中使用已解析的目标实体?,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,有src/AppBundle/Entity/ShoppingCart/Order.php解析OrderInterface,它可以很好地处理Doctrine 如果尝试在表单'class'=>OrderInterface::class中使用它,则我得到一个错误: 类“ShoppingCartBundle\Entity\OrderInterface”似乎不是托管条令实体。您忘了映射它了吗?“ 当然,可以直接定义'class'=>Order::class,但在这种情况下,解析目标实体配置将失去优势 sr

有src/AppBundle/Entity/ShoppingCart/Order.php解析OrderInterface,它可以很好地处理Doctrine

如果尝试在表单
'class'=>OrderInterface::class
中使用它,则我得到一个错误:

类“ShoppingCartBundle\Entity\OrderInterface”似乎不是托管条令实体。您忘了映射它了吗?“

当然,可以直接定义
'class'=>Order::class
,但在这种情况下,解析目标实体配置将失去优势

src/ComplaintsBundle/Form/Type/ComplaintType.php

app/config/config.yml


evm
EntityManager
的形式将
doctrine.dbal.connection.event\u manager
作为
em
注入

之后,您可以尝试以下内容:

private function resolveClass(string $className): string
{
    $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $this->em);
    $this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);

    $metadata = $eventArgs->getFoundMetadata();
    if ($metadata === null) {
        throw new InvalidArgumentException("Failed to resolve class $className");
    }

    return $metadata->getName();
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
        ->add('order', EntityType::class,
            array(
                'required'    => true,
                'class'       => $this->resolveClass(OrderInterface::class),
                'property'    => 'id',
            )
        );
}

实际上,我并没有对此进行测试,只是查看了一下。

真正的类名是在元数据加载期间解析的。 要通过接口获取真实的类名,应触发元数据加载。 这可以通过下一个代码实现

$entityManager = $managerRegistry->getManager();
$metadata = $entityManager->getClassMetadata(OrderInterface::class);
$realClassName = $metadata->getName();

感谢您的回答,不幸的是,它对我不起作用,可能是由于项目
“条令/orm”中使用的条令版本“~2.2,>=2.2.3,您的具体版本是什么?您可以使用
composer show
进行签出。为什么它不起作用?原则v2.4.8。它不起作用,因为在这个版本中没有类
OnClassMetadataNotFoundEventArgs
也没有
Events::onClassMetadataNotFound
我正在查看原则2.4的代码,我最好的猜测是使用原则2.4中的工作方式,解析程序实际上绑定到特定的关联,您需要解析特定的关联,而不是实体。您可以在本测试中看到它的示例
private function resolveClass(string $className): string
{
    $eventArgs = new OnClassMetadataNotFoundEventArgs($className, $this->em);
    $this->evm->dispatchEvent(Events::onClassMetadataNotFound, $eventArgs);

    $metadata = $eventArgs->getFoundMetadata();
    if ($metadata === null) {
        throw new InvalidArgumentException("Failed to resolve class $className");
    }

    return $metadata->getName();
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
        ->add('order', EntityType::class,
            array(
                'required'    => true,
                'class'       => $this->resolveClass(OrderInterface::class),
                'property'    => 'id',
            )
        );
}
$entityManager = $managerRegistry->getManager();
$metadata = $entityManager->getClassMetadata(OrderInterface::class);
$realClassName = $metadata->getName();