In php, I need a function to return all keys in array of objects. For arrays and objects I need keys like parentkey->key
. If the key is again an array, then I need parentkey->key->key1
.
My code as below
$array=json_decode('{"client":"4","gateWay":"1","store":"store.shop.com",
"valid":"true","po":34535,"additionalPO":23423,"customerNotes":"",
"orderItems":[{"item":"123","quantity":10,"supplierLotNo":"",
"customsValue":"","customsDescription":"","hsCode":""},
{"item":"345","quantity":50}],
"shippingInfos":[{"address":{"city":"Chennai",
"country":"India","postalCode":"86715","state":"TN",
"streetAddress1":"6971 North Street","streetAddress2":null},
"contact":{"company":null,"email":"info@store.com","firstName":"test",
"lastName":"test","phoneNo":null},"ServiceId":"3","thirdPartyAccountNo":"",
"signatureConfirmation":false,"saturdayDelivery":false}]}',true);
function array_keys_multi(array $array,$headkey,$pkey){
$keys = array();$hkey='';$parentkey='';
foreach ($array as $key => $value) {
//echo $key;
if($headkey!='' && !is_integer($headkey)){
if(!is_integer($key)){
if (is_array($value) || is_object($value)) {
if($pkey!='')
$parentkey=$pkey."->".$key;
else
$parentkey=$key;
foreach($value as $kk=>$val){
foreach($val as $kk1=>$val1){
$keys[]=$parentkey."->".$kk1;
}
}
//$keys[]=$parentkey."->".$key;
}else{
$keys[] = $pkey."->".$key;
$hkey=$headkey."->".$key;
}
}
}
else{
if(!is_integer($key)){
if($pkey!='')
$parentkey=$pkey."->".$key;
else
$parentkey=$key;
if (is_array($value) || is_object($value)) {
if($pkey!='')
$parentkey=$pkey."->".$key;
else
$parentkey=$key;
foreach($value as $kk=>$val){
//print_r($val);echo "==========";
foreach($val as $kk1=>$val1){
$keys[]=$parentkey."->".$kk1;
}
}
$hkey=$key;
}else{
$keys[]=$key;
}
}
}
if (is_array($value) || is_object($value)) {
echo $key."-----".$hkey."<br>";
$keys = array_merge($keys, array_keys_multi($value,$hkey,$key));
}
}
return $keys;
}
$k=array_keys_multi($array,'','');
print_r($k);
I need output as an array with the following key paths (notice no numeric keys are retained):
[
"client",
"gateWay",
"store",
"valid",
"po",
"additionalPO",
"customerNotes",
"orderItems->item",
"orderItems->quantity",
"orderItems->supplierLotNo",
"orderItems->customsValue",
"orderItems->customsDescription",
"orderItems->hsCode",
"shippingInfos->address->city",
"shippingInfos->address->country",
"shippingInfos->address->postalCode",
"shippingInfos->address->state",
"shippingInfos->address->streetAddress1",
"shippingInfos->address->streetAddress2",
"shippingInfos->contact->company",
"shippingInfos->contact->email",
"shippingInfos->contact->firstName",
"shippingInfos->contact->lastName",
"shippingInfos->contact->phoneNo",
"shippingInfos->ServiceId",
"shippingInfos->thirdPartyAccountNo",
"shippingInfos->signatureConfirmation",
"shippingInfos->saturdayDelivery"
]
How can I achieve this?
Starting from this very similar recursive snippet, I changed the key path separator and extended the algorithm to exclude numeric keys and parents with children.
Code: (Demo)
function getUniqueObjectKeyPaths($array, $parentKey = "") {
$keys = [];
foreach ($array as $parentKey => $v) {
if (is_array($v)) {
$nestedKeys = getUniqueObjectKeyPaths($v, $parentKey);
foreach($nestedKeys as $index => $key) {
if (!is_numeric($parentKey) && !is_numeric($key)) {
$nestedKeys[$index] = $parentKey . "->" . $key;
}
}
array_push($keys, ...$nestedKeys);
} elseif (!is_numeric($parentKey)) {
$keys[] = $parentKey;
}
}
return $keys;
}
var_export(getUniqueObjectKeyPaths($array));
Output:
array (
0 => 'client',
1 => 'gateWay',
2 => 'store',
3 => 'valid',
4 => 'po',
5 => 'additionalPO',
6 => 'customerNotes',
7 => 'orderItems->item',
8 => 'orderItems->quantity',
9 => 'orderItems->supplierLotNo',
10 => 'orderItems->customsValue',
11 => 'orderItems->customsDescription',
12 => 'orderItems->hsCode',
13 => 'orderItems->item',
14 => 'orderItems->quantity',
15 => 'shippingInfos->address->city',
16 => 'shippingInfos->address->country',
17 => 'shippingInfos->address->postalCode',
18 => 'shippingInfos->address->state',
19 => 'shippingInfos->address->streetAddress1',
20 => 'shippingInfos->address->streetAddress2',
21 => 'shippingInfos->contact->company',
22 => 'shippingInfos->contact->email',
23 => 'shippingInfos->contact->firstName',
24 => 'shippingInfos->contact->lastName',
25 => 'shippingInfos->contact->phoneNo',
26 => 'shippingInfos->ServiceId',
27 => 'shippingInfos->thirdPartyAccountNo',
28 => 'shippingInfos->signatureConfirmation',
29 => 'shippingInfos->saturdayDelivery',
)