Symfony OptionsResolver多维数组数组

时间:2019-05-21 07:42:19

标签: php symfony4 options-resolver

我有这种形式的rest api请求响应

{
    "first_field": null,
    "elements": [
        {
            "type": "type_1",
            "quantity": 234
        },
        {
            "type": "type_2",
            "quantity": 432
        },
        {
            "type": "type_3",
            "quantity": 112
        },
        {
            "type": "type_4",
            "quantity": 212
        }
    ],
    "third_field": {
        "option1": value1,
        "option2": "value2",
        "option3": "value3",
        "option4": "value4"
    }
}

我想将其传递给构造函数以创建对象。 我认为可以使用Symfony4 OptionsResolver对其进行配置。

虚假且不完整的示例

    class Status{

      public function __construct(array $options){
        $resolver = new OptionsResolver();
        $this->configureOptions($resolver);

        $this->options = $resolver->resolve($options);
        $this->init();
      }

     protected function init(){
       foreach($this->options['elements'] as $element){
         switch($element['type']){
           case 'type_1'
             $this->type1 = $element['quantity'];
             break;
           // And so on
         }
       }
     }

    }

如何在OptionsResolver中定义elements数组? 对于第三字段,解决方案是the nested options,但这是一个选项数组,而不是一个选项数组...

预先感谢

编辑 要从Json Object实例化一个新对象,一个很好的解决方案可以是karriere/json-decoder

1 个答案:

答案 0 :(得分:0)

如果仍然有人需要这样做,这是一种可能的实现方式

<?php

class Status
{
    public function __construct(array $options)
    {
        $resolver = new OptionsResolver();
        $this->configureOptions($resolver);

        $this->options = $resolver->resolve($options);
        $this->init();
    }

    protected function init()
    {
        foreach($this->options['elements'] as $element) {
            switch($element['type']) {
                case 'type_1':
                    $this->type1 = $element['quantity'];
                    break;
                // And so on
            }
        }
    }

    private function configureOptions(OptionsResolver $resolver)
    {
        $resolver->define('elements')
            ->allowedTypes('array[]')
            ->allowedValues(static function (array &$elements): bool {
                $subResolver = new OptionsResolver();

                $subResolver->define('type')
                    ->required()
                    ->allowedTypes('string');

                $subResolver->define('quantity')
                    ->required()
                    ->allowedTypes('int');

                // Trick is here: use array_map to resolve each elements one by one.
                $elements = array_map([$subResolver, 'resolve'], $elements);
                return true;
            });
    }
}