【发布时间】:2016-04-30 09:38:26
【问题描述】:
我从第三方获取 json 文件,其中键值对的深度可变,类似于: *** 编辑 JSON 以阐明将在 mysql db 中使用的表名。键是表中的列,值是数据。从 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 处理有一些速度优势)但无论哪种方式..我在分离嵌套数组和拉出底层数组时遇到了麻烦键:值。
我正在尝试这个:
$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 或其他用户对如何实现这一点有建议?
【问题讨论】:
-
您的 JSON 多处缺少逗号,缩进不一致。您能否修复它以便我们了解它的结构?
-
我可以——但这与这个问题有密切关系吗?我认为要传达的重要信息是它是嵌套的、未知的深度,并且初始键:值对不是嵌套数组的一部分,而是数组的顶层。我知道该示例不会通过 JSON 验证,但它只是为了说明。
-
现在有嵌套的错觉,其实
Array1、Array2等都是顶层对象的成员。我不确定这是否是故意的。在对很多结构没有硬编码的算法中,重要的是我们知道哪些结构是可选的。 -
你为什么不用这个:json_decode($object, true);
-
@Mojtaba - 我正在使用 json_decode 将对象转换为 $data1 数组,谢谢!