Php symfony 3.4:表单:允许实体的原型';孩子们
我的目标是创造一本书的章节,在每一章中,我可以有我想作为一个分章的章节。我有一个实体,它是一本书的一章 对于每一章,我都可以添加一个子章(实际上是另一章(但id parent不为null)) 我想用symfony表单添加/删除/修改每个章节,所以我有以下表单类型Php symfony 3.4:表单:允许实体的原型';孩子们,php,forms,symfony,collections,Php,Forms,Symfony,Collections,我的目标是创造一本书的章节,在每一章中,我可以有我想作为一个分章的章节。我有一个实体,它是一本书的一章 对于每一章,我都可以添加一个子章(实际上是另一章(但id parent不为null)) 我想用symfony表单添加/删除/修改每个章节,所以我有以下表单类型 public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('libelleLong', te
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('libelleLong', textType::class, ['label'=> 'titre']);
$builder->add('children', CollectionType::class,[
'entry_type' => ChapterType::class,
'entry_options' => ['label' => false,'block_name' => 'childrenList'],
'block_name' => 'childrenList',
'label'=> false,
'allow_add'=>true,
'allow_delete'=> true,
'prototype'=> true,
'by_reference' => false,
]
);
}
但是这句话'prototype'=>正确
放下一切
[19-May-2020 20:57:08 UTC]PHP致命错误:允许的内存大小为
中已耗尽134217728字节(尝试分配32768字节)
供应商\symfony\symfony\src\symfony\Component\Debug\Exception\OutOfMemoryException.php
在线1
我怎样才能让原型应用到孩子们身上?我相信,问题最终是递归。由于子窗体还将有一个
子窗体
字段,其中所有子窗体也将有子窗体
字段。。。无限的。因此,仅仅为了创建它,内存就耗尽了。(此问题仅在添加原型时出现,因为它随后必须呈现一个未来的子级,该子级也启用了原型,并且必须执行相同的操作-请注意,表单组件没有最佳配置来处理递归。也许您可以找到另一种技术上和视觉上处理此问题的方法,例如(pos、string、depth)元组,通过表单呈现/js和转换等进行光学改进)
因此,您必须限制此递归可以达到的深度。一种通用方法(我不确定这是否可行)是添加一个选项max_depth
,它本质上告诉表单生成器这是否可以达到以及可以达到多少级别
为此,表单类型类应该包括一个方法configureOptions
:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(['max_depth']);
$resolver->setDefaults([
'data_class' => Chapter::class, // you probably have this line!
'max_depth' => 3, // default value
]);
}
这将向表单类型添加配置选项,现在我们必须在buildForm
方法中使用它:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('libelleLong', textType::class, ['label'=> 'titre']);
// only add children sub form, if max_depth > 0, to stop infinite recursion
if($options['max_depth'] > 0) {
$builder->add('children', CollectionType::class,[
'entry_type' => ChapterType::class,
'entry_options' => [
'label' => false,
'block_name' => 'childrenList',
// IMPORTANT!!! reduce max_depth by 1
'max_depth' => $options['max_depth'] - 1,
],
'block_name' => 'childrenList',
'label'=> false,
'allow_add' => true,
'allow_delete'=> true,
'prototype'=> true,
'by_reference' => false,
]);
} // end if for max_depth
}
我建议保持max_depth
较小,比如2或3
另一种选择是,创建另一种表单类型,称为SubChapterType,也可能是SubChapterType,它本质上与ChapterType相同,只是它们的子类条目类型是下一种表单类型,其中最后一种表单类型没有子类字段。我认为,问题是最后一种表单类型这是递归。由于子窗体也将有一个子项
字段,其中所有子窗体也将无限地有子项
字段。因此,仅创建此子窗体的内存就会耗尽。(此问题仅在添加原型时出现,因为它随后必须呈现一个未来的子级,该子级也启用了原型,并且必须执行相同的操作-请注意,表单组件没有最佳配置来处理递归。也许您可以找到另一种技术上和视觉上处理此问题的方法,例如(pos、string、depth)元组,通过表单呈现/js和转换等进行光学改进)
因此,您必须限制此递归可以达到的深度。一种通用方法(我不确定这是否可行)是添加一个选项max_depth
,它本质上告诉表单生成器这是否可以达到以及可以达到多少级别
为此,表单类型类应该包括一个方法configureOptions
:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(['max_depth']);
$resolver->setDefaults([
'data_class' => Chapter::class, // you probably have this line!
'max_depth' => 3, // default value
]);
}
这将向表单类型添加配置选项,现在我们必须在buildForm
方法中使用它:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('libelleLong', textType::class, ['label'=> 'titre']);
// only add children sub form, if max_depth > 0, to stop infinite recursion
if($options['max_depth'] > 0) {
$builder->add('children', CollectionType::class,[
'entry_type' => ChapterType::class,
'entry_options' => [
'label' => false,
'block_name' => 'childrenList',
// IMPORTANT!!! reduce max_depth by 1
'max_depth' => $options['max_depth'] - 1,
],
'block_name' => 'childrenList',
'label'=> false,
'allow_add' => true,
'allow_delete'=> true,
'prototype'=> true,
'by_reference' => false,
]);
} // end if for max_depth
}
我建议保持max_depth
较小,比如2或3
另一种选择是,创建另一种表单类型,称为SubChapterType,也可能是SubChapterType,它本质上与ChapterType相同,只是它们的子项条目类型是下一个表单类型,其中最后一个表单类型没有子项字段。该限制很好非常感谢你的答案在短时间内的精确性!!!限制很好!!!!非常感谢你的答案在短时间内的精确性!!!