Формы Symfony (как автономный компонент с Doctrine) EntityType не работает

Я использую формы Symfony (v3.0) без остальной структуры Symfony. Использование Doctrine v2.5.

Я создал форму, вот класс типа формы:

class CreateMyEntityForm extends BaseFormType { public function buildForm(FormBuilderInterface $builder, array $options){ $builder->add('myEntity', EntityType::class); } } 

При загрузке страницы появляется следующая ошибка.

Аргумент 1 передан в Symfony \ Bridge \ Doctrine \ Form \ Type \ DoctrineType :: __ construct () должен быть экземпляром Doctrine \ Common \ Persistence \ ManagerRegistry, не указанным, вызываемым в / var / www / dev3 / Vendor / symfony / form /FormRegistry.php в строке 85

Я считаю, что есть некоторая конфигурация, которая нуждается в создании здесь, но я не знаю, как создать класс, который реализует ManagerRegistryInterface – если это правильно.

Любые указатели?

Изменить – вот мой код для создания Доктрины

 use Doctrine\ORM\EntityManager; use Doctrine\ORM\Tools\Setup; class Bootstrap { //...some other methods, including getCredentials() which returns DB credentials for Doctrine public function getEntityManager($env){ $isDevMode = $env == 'dev'; $paths = [ROOT_DIR . '/src']; $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, null, null, false); $dbParams = $this->getCredentials($env); $em = EntityManager::create($dbParams, $config); return $em; } } 

Поверь мне, ты просишь неприятностей!

EntityType::class работает, когда он интегрирован в рамки Symfony (есть волшебство под капюшонами – через DoctrineBundle). В противном случае вам нужно написать много кода для правильной работы.
Не стоит усилий!

ChoiceType::class проще создать репозиторий объектов и ввести его в конструктор форм, а затем использовать в поле ChoiceType::class . Что-то вроде:

 <?php # you form class namespace Application\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class InvoiceItemtType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('product', ChoiceType::class, [ 'choices' => $this->loadProducts($options['products']) ]); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['products' => [],]); # custom form option } private function loadProducts($productsCollection) { # custom logic here (if any) } } 

И где-то в приложении:

 $repo = $entityManager->getRepository(Product::class); $formOptions = ['products' => $repo->findAll()]; $formFactory = Forms::createFormFactory(); $formFactory->create(InvoiceItemtType::class, new InvoiceItem, $formOptions); 

В этом-то и дело!

Расширение ответа на вопрос хаббух.

Я смог реализовать EntityType в FormBuilder без лишней дополнительной работы. Однако он не работает с аннотациями, чтобы использовать Constraints непосредственно внутри объекта, что потребовало бы гораздо большей работы.

Вы можете легко облегчить требование ManagerRegistry расширения Doctrine ORM Forms Extension, расширив существующий AbstractManagerRegistry и создав собственное свойство контейнера в настраиваемом ManagerRegistry .

Тогда это просто вопрос регистрации расширения формы, как и любое другое расширение ( ValidatorExtension , HttpFoundationExtension и т. Д.).

МенеджерRegistry

 use \Doctrine\Common\Persistence\AbstractManagerRegistry; class ManagerRegistry extends AbstractManagerRegistry { /** * @var array */ protected $container = []; public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) { $this->container = $managers; parent::__construct($name, $connections, array_keys($managers), $defaultConnection, $defaultManager, $proxyInterfaceName); } protected function getService($name) { return $this->container[$name]; //alternatively supply the entity manager here instead } protected function resetService($name) { //unset($this->container[$name]); return; //don't want to lose the manager } public function getAliasNamespace($alias) { throw new \BadMethodCallException('Namespace aliases not supported'); } } $managerRegistry = new \ManagerRegistry('default', [], ['default' => $entityManager], null, 'default', 'Doctrine\\ORM\\Proxy\\Proxy'); с use \Doctrine\Common\Persistence\AbstractManagerRegistry; class ManagerRegistry extends AbstractManagerRegistry { /** * @var array */ protected $container = []; public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName) { $this->container = $managers; parent::__construct($name, $connections, array_keys($managers), $defaultConnection, $defaultManager, $proxyInterfaceName); } protected function getService($name) { return $this->container[$name]; //alternatively supply the entity manager here instead } protected function resetService($name) { //unset($this->container[$name]); return; //don't want to lose the manager } public function getAliasNamespace($alias) { throw new \BadMethodCallException('Namespace aliases not supported'); } } $managerRegistry = new \ManagerRegistry('default', [], ['default' => $entityManager], null, 'default', 'Doctrine\\ORM\\Proxy\\Proxy'); 

Настройте формы для использования расширения

 $extension = new \Symfony\Bridge\Doctrine\Form\DoctrineOrmExtension($managerRegistry); $formBuilder = \Symfony\Component\Form\FormFactoryBuilder::createFormFactoryBuilder(); $formBuilder->addExtension($extension); $formFactory = $formBuilder->getFormFactory(); 

Создать форму

 use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class UserType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('field_name', EntityType::class, [ 'class' => YourEntity::class, 'choice_label' => 'id' ]); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['data_class' => YourAssociatedEntity::class]); } } $form = $formFactory->create(new \UserType, $data, $options); 

Самый простой способ решить вашу проблему – зарегистрировать DoctrineOrmExtension с моста Doctrine, который гарантирует, что тип сущности зарегистрирован с необходимыми зависимостями.

Таким образом, процесс начальной загрузки компонента Form будет выглядеть следующим образом:

 // a Doctrine ManagerRegistry instance (you will probably already build this somewhere else) $managerRegistry = ...; $doctrineOrmExtension = new DoctrineOrmExtension($managerRegistry); // the list of form extensions $extensions = array(); // register other extensions // ... // add the DoctrineOrmExtension $extensions[] = $doctrineOrmExtension; // a ResolvedFormTypeFactoryInterface instance $resolvedTypeFactory = ...; $formRegistry = new FormRegistry($extensions, $resolvedTypeFactory);