如何在Laravel中使用JSONSchemaGenerator附加*如果数组中有多个重复对象 [英] How can attach * if multiple repeat object in array using JSONSchemaGenerator in laravel

查看:79
本文介绍了如何在Laravel中使用JSONSchemaGenerator附加*如果数组中有多个重复对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 json 生成架构时遇到问题,如果它们在array/json中重复出现,则不会附加多个对象/数组,例如(venue_id,total_users,unique_users,unique_percentage).我已经尝试了很多次,但是失败了.数据可以具有任何类型的API响应. json可能是这样的. https://jsoneditoronline.org/?id=7565670384c371680feee168d7db882e

I have problem when i generate the schema from json it is not attach with multiple object/array like (venue_id,total_users,unique_users,unique_percentage) if they are repeat in array/json. I have try many times but fail. Data may have any type of API response. json may be like this. https://jsoneditoronline.org/?id=7565670384c371680feee168d7db882e

我的json格式如下:

{

    "venues_details": {
        "frequency": "27%",
        "all_venue_details": [
            {
                "venue_id": "15",
                "total_users": "0",
                "unique_users": "0",
                "unique_percentage": "0%"
            },
            {
                "venue_id": "16",
                "total_users": "59",
                "unique_users": "42",
                "unique_percentage": "71%"
            },
            {
                "venue_id": "17",
                "total_users": "595",
                "unique_users": "94",
                "unique_percentage": "15%"
            }
        ]
    }
}

我的代码:

<?php
    use JSONSchemaGenerator\Generator;

    protected function convertSchemaToJson( $json_data )
    {
        $json_data = json_decode($json_data);
        $data = [];

        foreach ($json_data->properties as $key => $value) {
            if ($value->type == "object") {
                $this->traverseObject($value->properties,$key);
               $data = array_merge( $data, $this->treeData );
               $this->treeData = [];
               $this->keyString = '';
            } elseif ($value->type == "array") {
                foreach ($value->items->anyOf as $k => $v) {
                    if ($v->type == "object") {

                        $this->traverseObject($v->properties, $key);
                        $data = array_merge( $data, $this->treeData );

                        $this->treeData = [];
                        $this->keyString = '';
                    } else {
                        $data[$key] = ['type' => $v->type];

                    }//..... end if() .....//
                }//..... end foreach() ......//
            } else {
                $data[$key] = ['type' => $value->type];
            }//..... end if-else .....//
        }//..... end foreach() .....//

        return $data;
    }//..... end of convertSchemaToJson() .....//
    private function traverseObject( $object, $key )
    {
        foreach ($object as $k => $v) {
            $this->keyString .= !$this->keyString ? $key : ".".$key;
            if ($v->type == "object") {
                $this->traverseObject($v->properties, $k);
            } elseif ($v->type == "array") {
                foreach ($v->items->anyOf as $index => $val) {
                    if ($val->type == "object") {
                        if( !$this->retainedKey )
                            $this->retainedKey = $this->keyString;

                        $this->traverseObject($val->properties, $k);
                    } /*else {
                        $this->treeData[ $this->keyString.".".$k ] = ['type' => $val->type];
                        $this->keyString = $k;
                    }*/
                    $this->retainedKey = "";
                }//..... end foreach() ......//
            } else {
                $this->treeData[ $this->keyString.".".$k ] = ['type' => $v->type];
                $this->keyString = $this->retainedKey ? $this->retainedKey : "";

            }//..... end if() .....//
        }//..... end foreach() ......//
        return;
    }//..... end of traverseObject() .....//
    protected function generateJsonSchemaFromJson( $data )
    {
        $data = str_replace('null', '""', $data);
        return Generator::fromJson( $data );
    }//..... end of generateJsonSchemaFromJson() .....//


    $data = '{

    "venues_details": {
        "frequency": "27%",
        "name": "location area",
        "all_venue_details": [
            {
                "venue_id": "15",
                "total_users": "0",
                "unique_users": "0",
                "unique_percentage": "0%"
            },
            {
                "venue_id": "16",
                "total_users": "59",
                "unique_users": "42",
                "unique_percentage": "71%"
            },
            {
                "venue_id": "17",
                "total_users": "595",
                "unique_users": "94",
                "unique_percentage": "15%"
            }
        ]
    }
}';
        $schema =  Generator::fromJson( $data );
        $mapperJsonArr =   $this->convertSchemaToJson($schema);
        print_r($mapperJsonArr); 
?>

我的输出:

[
  "venues_details.frequency" => [
    "type" => "string"
  ],
  "venues_details.all_venue_details.*venue_id" => [
    "type" => "string"
  ],
  "venues_details.all_venue_details.*total_users" =>  [
    "type" => "string"
  ],
  "venues_details.all_venue_details.*unique_users" => [
    "type" => "string"
  ],
  "venues_details.all_venue_details.*unique_percentage" =>  [
    "type" => "string"
  ]
]

预期输出应为:

[
  "venues_details.frequency" => [
    "type" => "string"
  ],
  "venues_details.*all_venue_details.venue_id" => [
    "type" => "string"
  ],
  "venues_details.*all_venue_details.total_users" =>  [
    "type" => "string"
  ],
  "venues_details.*all_venue_details.unique_users" => [
    "type" => "string"
  ],
  "venues_details.*all_venue_details.unique_percentage" =>  [
    "type" => "string"
  ]
]

请帮助!

推荐答案

我将其重写为单个递归函数,而不是调试现有代码,该递归函数更易于阅读:

Rather than debug the existing code, I rewrote it as a single recursive function that is much easier to read:

function objToSchema($obj, &$branches, $branch=NULL) {
    foreach ((Array)$obj AS $name=>$elem) {
        switch (gettype($elem)) {
            case 'object':
                // Recurse!
                objToSchema($elem, $branches, (!is_numeric($name) ? $branch.($branch?'.':'').$name : $branch));
                break;
            case 'array':
                // Recurse!
                objToSchema($elem, $branches, (!is_numeric($name) ? $branch.($branch?'.':'').'*'.$name : $branch));
                break;
            case 'integer':
            case 'string':
            case 'double':
                // This is a value node. Prepare the final path and store the datatype in array
                $final = $branch.($branch?'.':'').$name;
                if (!in_array($final, array_keys($branches)))
                    $branches[$final] = ['type' => gettype($elem)];
                break;
        }
    }
}

调用:

$branches = [];
objToSchema(json_decode($sourceJson), $branches);

执行后,var_dump($branches)输出:

array(5) {
  ["venues_details.frequency"]=>
  array(1) {
    ["type"]=>
    string(6) "string"
  }
  ["venues_details.*all_venue_details.venue_id"]=>
  array(1) {
    ["type"]=>
    string(6) "string"
  }
  ["venues_details.*all_venue_details.total_users"]=>
  array(1) {
    ["type"]=>
    string(6) "string"
  }
  ["venues_details.*all_venue_details.unique_users"]=>
  array(1) {
    ["type"]=>
    string(6) "string"
  }
  ["venues_details.*all_venue_details.unique_percentage"]=>
  array(1) {
    ["type"]=>
    string(6) "string"
  }
}

这篇关于如何在Laravel中使用JSONSchemaGenerator附加*如果数组中有多个重复对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆