我从第三方获得json文件,具有类似于以下的可变深度的键:值对:***编辑了JSON以澄清将在mysqldb中使用的表名。KEY是表中的列,Value是数据。从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对,需要将表名设置为Array键,即Array1、Array2、Array3等。其中嵌套的Key是列名,Value是数据。
我一直在尝试使用RecursiveIteratorIterator重申数组(我知道这比数组的嵌套foreach处理有一些速度优势),但不管怎样。。我在分离嵌套数组和提取底层Key:Value时遇到了问题。
我正在尝试这个:
$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
但是,我需要使用数组的Key名称,而不是使用表名称的数字索引。也许olibiaz或其他用户对如何实现这一点有建议?
在所有评论和交流之后编辑。我会以你的例子更精确
<?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:非嵌套TableName,键:Key1,数据:Value1
TableName:非嵌套TableName,键:Key2,数据:Value2
TableName:非嵌套TableName,键:Key3,数据:Value3
表名称:表2,键:键1,数据:值1
表名称:表2,键:键2,数据:值2
表名称:表2,键:键3,数据:值3
表名称:表2,键:键1,数据:值1
表名称:表2,键:键2,数据:值2
表名称:表2,键:键3,数据:值3
表名称:表3,键:键1,数据:值1
表名称:表3,键:键2,数据:值2
表名称:表3,键:键3,数据:值3
表名:表4,键:键1,数据:值1
表名:表4,键:键2,数据:值2
表名:表4,键:键3,数据:值3
表名:表5,键:键1,数据:值1
表名:表5,键:键2,数据:值2
表名:表5,键:键3,数据:值3
也许您可以尝试json_decode
将JSON字符串转换为数组。它也处理嵌套级别。
试试看:http://php.net/manual/en/function.json-decode.php