修改:此问题涉及 Symfony 2.7 , Symfony 2.8 + 请参阅下面的Ogi答案。
我的require
中的composer.json
部分如下所示:
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.3.*",
"doctrine/orm": "~2.2,>=2.2.3,<2.5",
"doctrine/dbal": "<2.5",
"doctrine/doctrine-bundle": "~1.2",
"twig/extensions": "1.0.*",
"symfony/assetic-bundle": "~2.3",
"symfony/swiftmailer-bundle": "~2.3",
"symfony/monolog-bundle": "~2.4",
"sensio/distribution-bundle": "~2.3",
"sensio/framework-extra-bundle": "~3.0,>=3.0.2",
"sensio/generator-bundle": "~2.3",
"incenteev/composer-parameter-handler": "~2.0",
"braincrafted/bootstrap-bundle": "~2.0",
"twbs/bootstrap": "3.2.*",
"jquery/jquery": "1.11.*",
"stof/doctrine-extensions-bundle": "~1.1@dev"
},
注意:最后四个软件包是在Symfony2标准版之上添加的。
在Symfony 2 Forms文档章节之后,我尝试创建搜索表单。所以,我创建了一个实体类:
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class SearchQuery
{
/**
* @Assert\NotBlank()
* @Assert\Type(type="string", message="form.search.query.validation.type")
* @Assert\Length(
* min = 3,
* max = 50,
* minMessage = "form.search.query.validation.min",
* maxMessage = "form.search.query.validation.max"
* )
*/
protected $query;
public function __construct($query = '')
{
$this->setQuery($query);
}
public function getQuery()
{
return $this->query;
}
public function setQuery($query)
{
$this->query = $query;
}
}
表单类型:
<?php
namespace AppBundle\Form\Type;
use
Symfony\Component\OptionsResolver\OptionsResolverInterface,
Symfony\Component\Form\AbstractType,
Symfony\Component\Form\FormBuilderInterface
;
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('query', 'text', array(
'label' => '',
'attr' => array(
),
))
->add('save', 'submit', array(
'label' => '',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchQuery',
'attr' => array(
'id' => 'search-form'
)
));
}
public function getName()
{
return 'search';
}
}
渲染输出:
<form name="search" method="post" action="/app_dev.php/search" id="search-form" role="form">
<input type="search" id="search" name="search" required="required" class="form-control" value="">
<div class="form-group">
<label class="control-label required" for="search_query">Query</label>
<input type="text" id="search_query" name="search[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_save" name="search[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search__token" name="search[_token]" class="form-control" value="5f0e9c4a9d4e251fc62e25686cf810eaa0ff4331">
</form>
问题是Symfony 2 Forms,BraincraftedBootstrapBundle和Twig之间的某些东西试图发挥智能并添加这个不需要的字段:
<input type="search" id="search" name="search" required="required" class="form-control" value="">
我注意到只有SearchType::getName()
方法返回'search'
时才会发生这种情况。如果我将其更改为:
class SearchType extends AbstractType
{
[...]
public function getName()
{
return 'search_foo';
}
[...]
}
一切都按预期工作,渲染输出为:
<form name="search_foo" method="post" action="/app_dev.php/cautare" id="search-form" role="form">
<div id="search_foo">
<div class="form-group">
<label class="control-label required" for="search_foo_query">Query</label>
<input type="text" id="search_foo_query" name="search_foo[query]" required="required" class="form-control">
</div>
<div class="form-group">
<button type="submit" id="search_foo_save" name="search_foo[save]" class="btn btn-primary">Save</button>
</div>
<input type="hidden" id="search_foo__token" name="search_foo[_token]" class="form-control" value="68ee88cb3adef211b993806029ba3fa989322c80">
</div>
</form>
当然,我可以将名称更改为其他内容并继续前进,但它就像是在我脑海中敲打钉子而不了解窗帘背后真正发生的事情。
我甚至试图将field type设置为search
而不是text
,希望如果它看到有搜索字段会让我一个人赢得&#39 ; t尝试猜测我的意图是什么,但不是,它仍会打印出不需要的字段。
答案 0 :(得分:1)
您可能已经看到@aistis在其评论中创建的问题。
我从您的composer.json
文件中看到您似乎使用了symfony 2.3。所以这个错误很奇怪,因为它应该只发生在2.8 ......
无论如何,解决方案非常简单,但并不明显:您应该在表单类型中实现getBlockPrefix
方法:
<?php
namespace AppBundle\Form\Type;
// [...]
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// [...]
}
public function getBlockPrefix()
{
return 'app_search'
}
}
保持简短:这可以通过Symfony Form组件的最新更改来解释,删除表单别名和getName()
方法。
表单类型现在由其完全限定类名称标识
当一个表单被渲染时,它将从FQCN计算表单名称,只保留小写的&amp;蛇类名称减去Type
。然后它将使用此计算名称来呈现与此名称匹配的表单主题块。
然而,作为一个缺点,命名与现有表单类型相同的表单类型将导致您遇到的意外行为
好消息是,您可以通过覆盖表单类型中的getBlockPrefix
方法来覆盖表单主题名称的计算方式。因此,上面的解决方案。
PS:如果你真的使用Symfony 2.8+,你应该摆脱2.7中弃用的setDefaultOptions
方法,而不是新的configureOptions
:https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.7.md#form
另请参阅2.8中的Symfony Form组件的弃用和升级路径列表:https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form