0

I'm trying to grab all the keys of a multidimensional array and format them a certain way. Here's a partial array:

$ini_config['aaa']['email']['main'] = 'me@name.com';

$ini_config['bbb']['email']['ccc'] = 'you@name.com';
$ini_config['bbb']['phone']['local'] = '800-555-1212';
$ini_config['bbb']['phone']['skype'] = '744-222-1234';

$ini_config['ccc']['phone']['main'] = 'domain.com';
$ini_config['ccc']['domain']['https'] = 'https://www. domain.com';
$ini_config['ccc']['fax'] = '744-222-1237';

and here's the format I need them in:

aaa_email_main
bbb_email_ccc
bbb_phone_local
bbb_phone_skype
ccc_phone_main
ccc_domain_https
ccc_fax

This script is the closest I've been able to come to what I need:

<?php
rloop($ini_config);

function rloop($array) {
    global $full_key;

    foreach($array as $key => $value) {
        if(is_array($value) ) {
            $full_key .= $key .'_';
            $array[$key] = rloop($array[$key]);
        }
        else {
            $array[$key] = (string) $value;
            $filename = $full_key . $key;
            echo 'filename: '. $filename . PHP_EOL;
            $full_key = '';
        }
    }
}

N.B. The number of levels can be from 1 to 4, and all keys are strings.

Thanks

Frank Jance
  • 115
  • 1
  • 9

2 Answers2

1
$ini_config['aaa']['email']['main'] = 'me@name.com';
$ini_config['bbb']['email']['ccc'] = 'you@name.com';
$ini_config['bbb']['phone']['local'] = '800-555-1212';
$ini_config['bbb']['phone']['skype'] = '744-222-1234';
$ini_config['ccc']['phone']['main'] = 'domain.com';
$ini_config['ccc']['domain']['https'] = 'https://www. domain.com';
$ini_config['ccc']['fax'] = '744-222-1237';

function keyPaths(array $array, array $carry = [], string $separator = ''): array {
  foreach ($array as $key => $value) {
    if (is_array($value)) {
      $carry = keyPaths($value, $carry, $separator . $key . '_');
    } else {
      $carry[] = $separator . $key;
    }
  }
  return $carry;
}

$result = keyPaths($ini_config);
lukas.j
  • 6,453
  • 2
  • 5
  • 24
  • Thanks, Lucas. I'm trying to wrap my head around this solution. What is `$separator` used for? If I give it a character, it prepends it to the path. If I remove the variable from the function, half of the path is missing. Could you explain how this works? Thanks. – Frank Jance Jun 12 '22 at 04:09
  • keyPaths is a recursive function, with one argument: $array. $carry and $separator are optional arguments. You do not call keyPaths with them, only the code within keyPaths uses these two arguments on recursive calls. The name $separator is misleading, it comes from a first version of the code. A better name would be perhaps $keyPathWithSeparatorAtTheEnd (where separator means the underscore). – lukas.j Jun 12 '22 at 08:09
0

Thanks to @lucas.j here's what I'm using now:

function get_all_keys($array, $collector='') {
    $separator = '_';

    foreach ($array as $key => $value) {
        if (is_array($value)) {
            get_all_keys($value, $collector.$key.$separator);
        }
        else {
            $filename = $collector.$key;
            $content  = $value;
//          echo 'filename: '. $filename . PHP_EOL;  //:debug
//          echo 'content: ' . $content  . PHP_EOL;  //:debug
            file_put_contents($filename, $content);
        }
    }
}

After adding strategically placed echo statements, I was able to see what the $separator variable was doing. So I renamed it to $collector, since it's collecting the keys to form the "all-keys" string. I also renamed the function to be a little more descriptive, and added the hard-coded underscore to a new variable called $separator.

And since I don't need a new variable created, I dropped $carry and am performing what I need done directly in the else section.

Thanks, Lucas!

Frank Jance
  • 115
  • 1
  • 9