将嵌套的PHP JSON对象转换为PHP数组

时间:2018-04-28 20:55:10

标签: php arrays json

我需要一个将PHP嵌套的JSON对象/数组转换为关联数组的函数。

$final_array=[];
function toArray($initial,$json_object){
    foreach($json_object as $key => $value){
        if($value is string or integer or ...){  //Requires to be changed.
             $final_array[$initial.'/'.$key]=$value;
        }
        else{
             toArray($initial.'/'.$key,$value);
        }
    }
}

$json='{
    "name":{
         "first_name":"James",
         "last_name":"Bond"
     },
     "aliases":["007","Bond"],
     "profiles":[{"0":"unknown"},"007",{"2":"secret agent"}]
}';

toArray('/Bond',json_decode($json));

foreach($final_array as $key=>$value){
     echo $key.' - '.$value;
}

所需的输出是:

/Bond/name/first_name - James
/Bond/name/last_name - Bond
/Bond/aliases/0 - 007
/Bond/aliases/1 - Bond
/Bond/profiles/0/0 - Unknown
/Bond/profiles/1 - 007
/Bond/profiles/2 - secret agent

我必须在代码中进行哪些更改才能获得所需的功能?

4 个答案:

答案 0 :(得分:2)

这似乎有效:

<?php
function wtf(string $root_name,Iterable $data){
    foreach($data as $name=>$val){
        if(is_iterable($val)){
            wtf($root_name."/".$name,$val);
        }else{
            echo $root_name."/$name - $val"."\n";
        }
    }
}


$json='{
    "name":{
         "first_name":"James",
         "last_name":"Bond"
     },
     "aliases":["007","Bond"],
     "profiles":[{"0":"unknown"},"007",{"2":"secret agent"}]
}';
$data=json_decode($json,true);
wtf('/bond',$data);

输出:

/bond/name/first_name - James
/bond/name/last_name - Bond
/bond/aliases/0 - 007
/bond/aliases/1 - Bond
/bond/profiles/0/0 - unknown
/bond/profiles/1 - 007
/bond/profiles/2/2 - secret agent

答案 1 :(得分:1)

将其转换为通用对象数据类型,然后将其构建出来。

这可能会有所帮助 -

static void print<T>(T x) {
    Console.WriteLine(x);
}

答案 2 :(得分:1)

这是一个解决方案:

<?php

function getPaths($a, $output = Array(), $parents = array()) {
    // resetting path
    $path = $parents;

    // walk through the items
    foreach($a as $key => $value) {     
        if(is_array($value)) {
            $path[] = $key;
            // get the sub-items
            $output = getPaths($value, $output, $path);
        } else {
            $path[] = $key;
            // build return array
            $x = ["path" => $path, "value" => $value];
            // add that to output
            $output[] = $x;

        }
        $path = $parents; // again a reset..
    }
    return $output;
}

// usage:

$json='{
    "name":{
         "first_name":"James",
         "last_name":"Bond"
     },
     "aliases":["007","Bond"],
     "profiles":[{"0":"unknown"},"007",{"2":"secret agent"}]
}';
$array = json_decode($json, true);

foreach(getPaths($array) as $item) {
    echo "Bond/".implode("/",$item['path']) . " - {$item['value']} <br>";
}

输出:

  

Bond / name / first_name - James
  Bond / name / last_name - 债券
  债券/别名/ 0 - 007
  债券/别名/ 1 - 债券
  债券/个人资料/ 0/0 - 未知
  债券/简介/ 1 - 007
  债券/个人资料/ 2/2 - 秘密特工

答案 3 :(得分:0)

我的pathify()函数在函数内部声明了一个存储变量$output,它可以从递归过程中的任何地方接收推送数据,因为它可以通过引用修改(由&符号表示之前变量)。

只要$v是一个数组,该函数就会使用更新/扩展的$path值调用自身。当$v不再是数组时,路径值会附加-,然后$v

通过调用implode("\n", pathify(...)),我的方法确保没有悬空/额外换行符 - 仅在可见字符串之间。

代码:(Demo

function pathify($array, $path, &$output = []){  // declare $output as an empty array by default and modify by reference
    foreach($array as $k => $v){
        if (is_array($v)) {                      // if can recurse
            pathify($v, "$path/$k", $output);    // append key to path, access $v array
        }else{
            $output[] = "$path/$k - $v";         // push completed string to output array
        }
    }
    return $output;                              // return array of path strings
}

$json='{
    "name":{
         "first_name":"James",
         "last_name":"Bond"
     },
     "aliases":["007","Bond"],
     "profiles":[{"0":"unknown"},"007",{"2":"secret agent"}]
}';

$data = json_decode($json, true);              // decode json to an array
echo implode("\n", pathify($data, "/Bond1"));  // separate the returned string with a newline
echo "\n-------\n";
echo implode("\n", pathify([], "/Bond2"));     // separate the returned string with a newline
echo "\n-------\n";
echo implode("\n", pathify([], "/Bond3"));     // separate the returned string with a newline
echo "\n-------\n";
echo implode("\n", pathify($data, "/Bond4"));  // separate the returned string with a newline
echo "\n-------\n";
echo implode("\n", pathify($data, "/Bond5"));  // separate the returned string with a newline

输出:

/Bond1/name/first_name - James
/Bond1/name/last_name - Bond
/Bond1/aliases/0 - 007
/Bond1/aliases/1 - Bond
/Bond1/profiles/0/0 - unknown
/Bond1/profiles/1 - 007
/Bond1/profiles/2/2 - secret agent
-------

-------

-------
/Bond4/name/first_name - James
/Bond4/name/last_name - Bond
/Bond4/aliases/0 - 007
/Bond4/aliases/1 - Bond
/Bond4/profiles/0/0 - unknown
/Bond4/profiles/1 - 007
/Bond4/profiles/2/2 - secret agent
-------
/Bond5/name/first_name - James
/Bond5/name/last_name - Bond
/Bond5/aliases/0 - 007
/Bond5/aliases/1 - Bond
/Bond5/profiles/0/0 - unknown
/Bond5/profiles/1 - 007
/Bond5/profiles/2/2 - secret agent

非常感谢@hanshenrik通过我使用static $output声明的第一个答案警告我对功能可重用性的严重影响。如果有兴趣研究这个缺点,请阅读以下页面和评论static keyword inside function?