Symfony 5 表单创建失败

Symfony 5 form creation failing

我用 php bin/console make:entity 命令向我的项目 ( BookAuthor, BookSeries ) 添加了 2 个实体,然后我用 [=14= 生成了一个表单 class ]命令。

在测试时我添加了一些作者但是当我尝试打开 add/Series 路由时我收到了这个错误消息:

Object of class App\Entity\BookAuthor could not be converted to string

来自 Form Builder 的相关代码 class:

class BookSeriesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('description')
            ->add('SeriesAuthor', )
            ->add('Submit', SubmitType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => BookSeries::class,
        ]);
    }
}

SeriesAuthor 应该从数据库中获取可用作者列表。

BookSeries 与 BookAuthor 实体具有 OneToMany 关系。当 BookAuthor table 为空时,页面在添加作者后加载正常,页面开始出现错误

来自Controller.php文件的相关代码:

public function addBookSeries(Request $request)
    {
        $new_series = new BookSeries();
        $form = $this->createForm(BookSeriesType::class, $new_series);

        $form->handleRequest($request);
        if($form->isSubmitted() && $form->isValid()){

            $em = $this->getDoctrine()->getManager();
            $em->persist($new_series);
            $em->flush();

            return $this->redirect($this->generateUrl('post.manage'));
        }
        return $this->render("post/create.html.twig",[
            'form' => $form->createView()
        ]);

来自错误的 StackTrace:

Error:
Object of class App\Entity\BookAuthor could not be converted to string

  at C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\doctrine-bridge\Form\Type\DoctrineType.php:58
  at Symfony\Bridge\Doctrine\Form\Type\DoctrineType::createChoiceLabel(object(BookAuthor), 0, '2')
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ChoiceList\Factory\DefaultChoiceListFactory.php:179)
  at Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory::addChoiceView(object(BookAuthor), '2', array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceLabel'), array(0), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceName'), null, null, array(), array(), array())
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ChoiceList\Factory\DefaultChoiceListFactory.php:248)
  at Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory::addChoiceViewsFromStructuredValues(array('2'), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceLabel'), array(object(BookAuthor)), array(0), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceName'), null, null, array(), array(), array())
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ChoiceList\Factory\DefaultChoiceListFactory.php:143)
  at Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory->createView(object(LazyChoiceList), null, array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceLabel'), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceName'), null, null)
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ChoiceList\Factory\PropertyAccessDecorator.php:220)
  at Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator->createView(object(LazyChoiceList), array(), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceLabel'), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceName'), null, null)
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ChoiceList\Factory\CachingFactoryDecorator.php:225)
  at Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator->createView(object(LazyChoiceList), array(), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceLabel'), array('Symfony\Bridge\Doctrine\Form\Type\DoctrineType', 'createChoiceName'), null, null)
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Extension\Core\Type\ChoiceType.php:437)
  at Symfony\Component\Form\Extension\Core\Type\ChoiceType->createChoiceListView(object(LazyChoiceList), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Extension\Core\Type\ChoiceType.php:205)
  at Symfony\Component\Form\Extension\Core\Type\ChoiceType->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ResolvedFormType.php:146)
  at Symfony\Component\Form\ResolvedFormType->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:103)
  at Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\ResolvedFormType.php:143)
  at Symfony\Component\Form\ResolvedFormType->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy.php:103)
  at Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label' => null, 'label_format' => null, 'label_translation_parameters' => array(), 'attr_translation_parameters' => array(), 'translation_domain' => null, 'auto_initialize' => true, 'trim' => false, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'method' => 'POST', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'allow_file_upload' => false, 'help_translation_parameters' => array(), 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'expanded' => false, 'block_prefix' => null, 'row_attr' => array(), 'label_html' => false, 'attr' => array(), 'data_class' => null, 'multiple' => false, 'empty_data' => '', 'required' => true, 'error_bubbling' => false, 'label_attr' => array(), 'compound' => false, 'action' => '', 'upload_max_size_message' => object(Closure), 'help' => null, 'help_attr' => array(), 'help_html' => false, 'is_empty_callback' => null, 'validation_groups' => null, 'constraints' => array(), 'choices' => null, 'choice_filter' => null, 'em' => object(EntityManager), 'class' => 'App\Entity\BookAuthor', 'query_builder' => null, 'id_reader' => object(IdReader), 'choice_loader' => object(ChoiceLoader), 'choice_label' => object(ChoiceLabel), 'choice_name' => object(ChoiceFieldName), 'choice_value' => object(ChoiceValue), 'choice_attr' => null, 'preferred_choices' => array(), 'group_by' => null, 'placeholder' => null, 'choice_translation_domain' => false))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Form.php:1041)
  at Symfony\Component\Form\Form->createView(object(FormView))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\form\Form.php:1044)
  at Symfony\Component\Form\Form->createView()
     (C:\xampp\htdocs\project-php-7.3-dev\src\Controller\BookDataController.php:59)
  at App\Controller\BookDataController->addBookSeries(object(Request))
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\http-kernel\HttpKernel.php:157)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\http-kernel\HttpKernel.php:79)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (C:\xampp\htdocs\project-php-7.3-dev\vendor\symfony\http-kernel\Kernel.php:196)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (C:\xampp\htdocs\project-php-7.3-dev\public\index.php:28) 

错误消息说明了您需要知道的一切。您正在尝试将对象转换为字符串。在这种情况下,BookAuthor。我假设这些实体之间存在一对多或多对多的关系。在这种情况下,在 BookSeriesType 中,SeriesAuthor 应该是 EntityType. A helpful reference

SymfonyCasts 上的 tutorial 帮我解决了。

显然我必须稍微配置一下表单生成器。

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('seriesAuthor', EntityType::class, [
                'class' => BookAuthor::class,
                'choice_label' => function(BookAuthor $author) {
                    return sprintf('%s %s', $author->getFirstname(), $author->getLastname());
                },
                'placeholder' => 'Choose an author'
            ])
            ->add('description')
            ->add('Submit', SubmitType::class)
        ;
    }