1

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":"[email protected]","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?

0

1 Answer 1

1

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',
)
Sign up to request clarification or add additional context in comments.

3 Comments

thank you.you saved my time.i am struggling from a week. it is working amazingly.
please see my edited question.I need to skip first parent orders.
If you are changing the requirements, please ask a new question with a new, clear minimal reproducible example and reference this page in your new question. Show your new code which fails to modify my answer to suit your new requirements. I have rolled back your edit so that it does not invalidate my working answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.