解析未知深度

时间:2016-04-29 18:00:34

标签: php json

我从第三方获取json文件,其中包含可变深度的键:值对,类似于: ***编辑JSON以澄清将在mysql db中使用的表名。 KEY是表中的列,值是数据。列名称将是从json到json的静态。

   {                         
   "Key1": "Value1",  //non-nested key:value go to default table                     
   "Key2": "Value2",                      
   "Key3": "Value3",                                 
   "Table1": [],                      
   "Table2": [{                      
        "Key1": "Value1",                  
        "Key2": "Value2",                  
        "Key3": "Value3"},

        {"Key1": "Value1",                  
         "Key2": "Value2",                  
         "Key3": "Value3"}],

    "Table3": [
          {"Key1": "Value1",                  
            "Key2": "Value2",                  
            "Key3": "Value3"},
             {"Table4": [
                   {"Key1": "Value1",              
                    "Key2": "Value2",              
                    "Key3": "Value3"},
                {"Table5": [
                           {"Key1": "Value1",          
                            "Key2": "Value2",          
                            "Key3": "Value3"}]
                 }]
           }]    
     }

**此示例传递JSON验证

对于初始密钥:值对(不在嵌套数组中)我需要设置一个表名,将所有非嵌套值插入表中。对于嵌套的Key:Value对,需要将tablename设置为Array键,即Array1,Array2,Array3等,其中嵌套的Key是列名,Value是数据。

我一直在尝试使用RecursiveIteratorIterator来重申数组(我理解这对于数组的嵌套foreach处理有一些速度优势),但无论哪种方式..我在分离嵌套数组和拔出底层数据时遇到问题键:值

我正在尝试这个:

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($data1),
    RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $key=>$value){
        if (!is_array($value)){
        //echo $key." KEY is not an array <br>";
        }

        if(is_array($value)){
            //echo $key." KEY is an array <br>";
                foreach($value as $key1=>$val1){
                    if (is_array($val1)){
                    //echo $key1."KEY 1 is an array<br>";  
                }
            }    
        }
    }    

更新

用户@olibiaz提出了几乎100%正确的解决方案:

function toto(array $input, $tableName = '')
{
    foreach ($input as $key => $element) {
      if (is_array($element)) {
         toto($element, $key);
      } else {
          if ($tableName === '') {
             // here is the non nested elelement,
             // you can choose the tableName you want
             $tableName = 'NonNestedTableName';
          }
          // place your insert here or whatever you want
          // here, the tablename is the index of the nested array
          echo "TableName: $tableName, Key: $key, Data: $element \n";
      }
    }
}

以下是我在JSON数据上运行上述代码时得到的输出:

TableName: project, Key: Key1, Data: Value1 // "project" used for non-nested
TableName: project, Key: Key2, Data: Value2 
TableName: project, Key: Key3, Data: Value3
TableName: 0, Key: Key1, Data: Value1  // Tablename needs to be "Array2"
TableName: 0, Key: Key2, Data: Value2  // for these 3 data sets
TableName: 0, Key: Key3, Data: Value3 
TableName: 1, Key: Key1, Data: Value1  // Tablename needs to be "Array2"
TableName: 1, Key: Key2, Data: Value2 
TableName: 1, Key: Key3, Data: Value3 
TableName: 0, Key: Key1, Data: Value1  // Tablename needs to be "Array3"
TableName: 0, Key: Key2, Data: Value2 
TableName: 0, Key: Key3, Data: Value3  
TableName: 0, Key: Key1, Data: Value1  // Tablename needs to be "Array4"
TableName: 0, Key: Key2, Data: Value2 
TableName: 0, Key: Key3, Data: Value3 
TableName: 0, Key: Key1, Data: Value1  // Tablename needs to be "Array5"
TableName: 0, Key: Key2, Data: Value2 
TableName: 0, Key: Key3, Data: Value3

但是,我不需要使用表名的数字索引,而是需要使用数组的键名。也许olibiaz或其他用户有关于如何实现这一目标的建议?

2 个答案:

答案 0 :(得分:0)

在所有评论和交流之后编辑。我会以你的例子来更精确地

<?php

$inputJson = '{                         
   "Key1": "Value1",                      
   "Key2": "Value2",                      
   "Key3": "Value3",                                 
   "Table1": [],                      
   "Table2": [{                      
      "Key1": "Value1",                  
      "Key2": "Value2",                  
      "Key3": "Value3"},
     {
        "Key1": "Value1",                  
        "Key2": "Value2",                  
        "Key3": "Value3"}],
   "Table3": [{
        "Key1": "Value1",                  
        "Key2": "Value2",                  
        "Key3": "Value3"},
         {
           "Table4": [{
              "Key1": "Value1",              
              "Key2": "Value2",              
              "Key3": "Value3"},
           {
              "Table5": [{
                 "Key1": "Value1",          
                 "Key2": "Value2",          
                 "Key3": "Value3"}]
             }]
       }]    
 }';

所以输入和你一样,那么这里是递归函数

function toto(array $input, $tableName = '')
{
    foreach ($input as $key => $element) {
        if (is_array($element)) {
            // if key is integer its the first level of array so we keep the $tablename - edited part
            $key = is_int($key) ? $tableName : $key;
            toto($element, $key);
        } else {
            if ($tableName === '') {
                $tableName = 'NonNestedTableName';
            }
            echo "TableName: $tableName, Key: $key, Data: $element \n";
        }
    }
}

$inputArray = json_decode($inputJson, true);

toto($inputArray);

这将显示

  

TableName:NonNestedTableName,Key:Key1,Data:Value1

     

TableName:NonNestedTableName,Key:Key2,Data:Value2

     

TableName:NonNestedTableName,Key:Key3,Data:Value3

     

TableName:Table2,Key:Key1,Data:Value1

     

TableName:Table2,Key:Key2,Data:Value2

     

TableName:Table2,Key:Key3,Data:Value3

     

TableName:Table2,Key:Key1,Data:Value1

     

TableName:Table2,Key:Key2,Data:Value2

     

TableName:Table2,Key:Key3,Data:Value3

     

TableName:Table3,Key:Key1,Data:Value1

     

TableName:Table3,Key:Key2,Data:Value2

     

TableName:Table3,Key:Key3,Data:Value3

     

TableName:Table4,Key:Key1,Data:Value1

     

TableName:Table4,Key:Key2,Data:Value2

     

TableName:Table4,Key:Key3,Data:Value3

     

TableName:Table5,Key:Key1,Data:Value1

     

TableName:Table5,Key:Key2,Data:Value2

     

TableName:Table5,Key:Key3,Data:Value3

答案 1 :(得分:-1)

也许您可以尝试json_decode将JSON字符串转换为数组。它确实照顾了嵌套级别。

试一试:http://php.net/manual/en/function.json-decode.php