My pathify() function declares a storage variable $output inside the function which can receive pushed data from anywhere in the recursive process because it is modifiable by reference (denoted by the & symbol before variable).
As long as $v is an array, the function will call itself with the updated/extended $path value. When $v ceases to be an array, the path value is appended with a - then $v.
By calling implode("\n", pathify(...)), my approach ensure that there are no dangling/extra newline characters -- only between visible strings.
Code: (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
Output:
/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
Big thanks to @hanshenrik for alerting me to the crippling impact on function re-usability with my first answer which used a static $output declaration. If interested in researching this drawback please, read the following page and the comments. static keyword inside function?
json_decode($json, true)?