我对Symfony(v 2.3.2)表格有一个奇怪的问题。没有关系,这是非常简单的形式。我还应该注意,此表单仅用于REST API。
所以我有一个已发布的字段(布尔值)。在实体上,默认设置为false。
在更新时,REST API客户端发送正确的PUT请求...&[entity]published=0&...
。该值也在表格参数中的Symfony profiler中显示。
但是我注意到数据库中的实际值设置为true(或者是1,因为它的tinyint)。
因此,为了找出问题所在,我在$form->submit($request);
throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->get('published')->getData()));
或
throw new \Exception(sprintf('Request: %s, form: %s', $request->get('entity')['published'], $form->getData()->getPublished()));
异常消息显示:Request: 0, form: 1
。这意味着在submit方法的某处,字符串值'0'将转换为1。
该字段由$builder->add('published', 'checkbox', [ 'required' => false ])
此外,我注意到奇怪的事情,这可能是相关的。在Symfony分析器,面板请求中,我收到错误:Warning: json_encode(): Invalid UTF-8 sequence in classes.php line 3758
,我没有发送任何奇怪的字符 - 只是单词“test”。
答案 0 :(得分:5)
您不应在API中使用复选框表单类型,0并不代表错误。
你应该实现一个新的布尔表单类型,它转换1,' 1'并且真实,其他一切都是假的(例如)。
以下是一个示例:https://gist.github.com/fsevestre/abfefe0b66e5f5b24c60
答案 1 :(得分:2)
进一步调查发现,典型的HTML表单复选框仅在选中时发送给服务器。所以我假设将值设置为0 | false | off会使其工作,就像将它设置为true一样。
因此,如果您将表单窗口小部件设置为键入复选框,则如果要将其设置为false,请不要在请求中发送复选框。就我而言,它看起来像这样:
Array
(
[entity] => Array
(
[id] => 73
[_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d
)
)
否则发送任何内容,0,false,off也会起作用
Array
(
[entity] => Array
(
[id] => 73
[published] => 1|0|false|on|off
[_token] => d63dad39ea458f7d3c7ae5dbea10c325cb9ee93d
)
)
答案 2 :(得分:0)
使用PUT时,这有点问题...... 我通过在所有解决此问题的表单中添加订阅者来解决这个问题(此代码也解决了使用PUT而不填充所有数据的问题):
class RestFormSubscriber implements EventSubscriberInterface {
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(FormEvents::PRE_SUBMIT => "preSubmit");
}
/**
* Remove null fields on update
* Fixes boolean value
* @param FormEvent $event
*/
public function preSubmit(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
$isPUT = strtoupper($form->getConfig()->getMethod()) == "PUT";
$accessor = PropertyAccess::createPropertyAccessor();
foreach ($form->all() as $name => $child) {
if ($isPUT && !isset($data[$name])) {
$form->remove($name);
continue;
}
if(is_bool($accessor->getValue($form->getData(), $name))) {
$val = $data[$name];
$data[$name] = ($val=="true")||($val=="1")||($val=="on");
}
}
$event->setData($data);
}
}