Search code examples
phparraysrecursioncamelcasingsnakecasing

Recursively convert all keys from camelCase to snake_case


My array looks some what like this (is has multiple sub arrays)

[
    'reportId' => '20210623-da1ece3f'
    'creationDate' => '2021-06-23 19:50:15'
    'dueDate' => '2021-06-24 19:50:15'
    'data' => [
        'vehicleDetails' => [
            'chassisNumber' => 'xxxxx-xxxxxx'
            'make' => 'Honda'
            'model' => 'City'
            'manufactureDate' => '2000'
            'body' => 'xxx-xxxxx'
            'engine' => 'xxx-xxx'
            'drive' => 'FF'
            'transmission' => 'MT'
        ]
]

i'm trying to rename all keys from chassisNumber to chassis_number. This is what i've done so far

function changeArrayKeys($array)
{
    if(!is_array($array)) return $array;
    $tempArray = array();
    foreach ($array as $key=>$value){
        if(is_array($value)){
            $value = changeArrayKeys($value);
        }else{
            $key  = strtolower(trim(preg_replace('/([A-Z])/', '_$1', $key)));
        }
        $tempArray[$key]=$value;
    }
    return $tempArray;
}

print_r(changeArrayKeys($data)); die;

This code kind of works. it just doesn't replace the sub keys. like here

'data' => [
        'vehicleDetails' => [ ]
]

but inside vehicleDetails[] it replace properly. Any idea what im missing here? or is there a better and more efficient way to do this instead of recursively ?


Solution

  • This looks pretty obvious to me:

            if(is_array($value)){
                $value = changeArrayKeys($value);
            }else{
                $key  = strtolower(trim(preg_replace('/([A-Z])/', '_$1', $key)));
            }
    

    If the $value is an array, you do a recursive call, but you do not change the key of that nested array in any way. It could help to move the $key manipulation out of the else branch