如何使用 FOSRestBundle 和 symfony 形式处理嵌套 json

How to process nested json with FOSRestBundle and symfony forms

嵌套 json 我的意思是将地址数据保存在自己的 "address" 数组中:

{
  "user": {
    "id": 999,
    "username": "xxxx",
    "email": "xxxx@example.org",
    "address": {
      "street": "13th avenue",
      "place": 12
    }
  }
}

而不是扁平的

{
  "user": {
    "id": 999,
    "username": "xxxx",
    "email": "xxxx@example.org",
    "street": "13th avenue",
    "place": 12
  }
}

使用用户实体及其属性 "id"、"username" 和 "email" 可以很好地 there 处理平面图。使用 symfony 表单功能对其进行了很好的验证:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('username');
    $builder->add('email', 'email');
    $builder->add('password', 'password');
    $builder->add('street');
    $builder->add('place');
}

我想将 "street" 和 "place" 作为用户实体中的属性,使用原则将其全部存储在数据库中的一个用户 table 中。但是我得到的json来自第三方,所以我无法修改。

是否有任何构建表单的方法,以便它可以正确验证 json 和 "address" 字段,仍然能够将所有用户数据保存在一个 table 中?

这是个很好的问题。想到的一种解决方案是使用表单事件手动制作未映射的表单并绑定数据,例如:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // Make a "nested" address form to resemble JSON structure
    $addressBuilder = $builder->create('address', 'form')
        ->add('place')
        ->add('street');

    $builder->add('username');
    $builder->add('email', 'email');
    $builder->add('password', 'password');
    // add that subform to main form, and make it unmapped
    // this will tell symfony not to bind any data to user object
    $builder->add($addressBuilder, null, ['mapped' => false]);

    // Once form is submitted, get data from address form
    // and set it on user object manually
    $builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
        $user = $event->getData();
        $addressData = $event->getForm()->get('address')->getData();

        $user->setStreet($addressData['street']);
        $user->setPlace($addressData['place']);
    })
}