Symfony 5.4自定义ButtonType无法读取属性问题排查
问题场景
在Symfony 5.4项目中使用Symfony Form:
- 项目基于DTO构建表单,默认
ButtonType已有Twig主题的特殊容器处理 - 需创建自定义ButtonType以实现独立的主题渲染,编写了如下自定义类型:
class FormAddButtonType extends AbstractType { public const BLOCK_PREFIX = 'formaddbutton'; public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'attr' => [ 'class' => 'button blue-button', ], ]); } public function getBlockPrefix(): string { return self::BLOCK_PREFIX; } public function getParent(): string { return ButtonType::class; } }
在表单中添加两个按钮后:
public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('test_button_1', ButtonType::class, [ 'label' => 'Test Button 1', 'attr' => [ 'class' => 'button blue-button', ], 'row_attr' => ['class' => 'noborder'], ]); $builder->add('test_button_2', FormButtonType::class, [ 'label' => 'Test Button 2', 'attr' => [ 'class' => 'button blue-button', ], 'row_attr' => ['class' => 'noborder'], ]); }
默认按钮test_button_1正常渲染,自定义按钮test_button_2抛出错误:
Can't get a way to read the property "test_button_2" in class "My\Name\Space\Dto\MyDataDto"
注:DTO中无test_button_1和test_button_2属性,手动设置'mapped' => false无效;但在自定义CollectionType的POST_SET_DATA监听器中添加该自定义按钮则正常。
问题原因与解决方案
原因1:未继承父类默认选项
Symfony默认ButtonType的mapped选项默认值为false,但你的自定义类型在configureOptions中未调用父类方法,导致丢失了这个关键默认配置,Symfony会尝试将按钮字段映射到DTO属性。
原因2:类名笔误
自定义类型类名为FormAddButtonType,但添加按钮时使用了FormButtonType,这会导致Symfony无法识别正确的类型,可能引发额外的配置继承问题。
修复步骤
- 继承父类配置:在自定义类型的
configureOptions中先调用父类方法,确保继承所有默认选项:
public function configureOptions(OptionsResolver $resolver): void { parent::configureOptions($resolver); // 必须先调用父类方法 $resolver->setDefaults([ 'attr' => [ 'class' => 'button blue-button', ], ]); }
- 修正类名:将表单中的
FormButtonType改为正确的FormAddButtonType:
$builder->add('test_button_2', FormAddButtonType::class, [ 'label' => 'Test Button 2', 'attr' => [ 'class' => 'button blue-button', ], 'row_attr' => ['class' => 'noborder'], ]);
完成以上两步后,自定义按钮即可正常渲染,不会再触发属性映射错误。
内容的提问来源于stack exchange,提问作者Exterior
相关产品推荐
相关产品推荐

