Chris Starling Chris Starling - 5 months ago 9
PHP Question

Add/edit values in a multidimensional array using an array of key names

I have an array of key names of variable length and I want to use those names to assign a value to an array

for example, I have an array that lists the number of cars and bikes of different makes:

$vehicles = [
'cars' => Array
(
'suzuki' => Array
(
'wagon' => 4,
'baleno' => 2
),
'honda' => Array
(
'civic' => 6
)
),
'bikes' => array
(
'raleigh' => 3,
'scott' => 3
)
];


I also have several arrays of key names along with values to put in the main array:

$keys1 = ['cars', 'honda', 'jazz'];
$value1 = 3;
$keys2 = ['bikes', 'scott'];
$value2 = 1;
$keys3 = ['motorbikes', 'harley-davidson', 'dyna', 'street-bob'];
$value3 = 2;


After inputting all these values the array should look like this:

$vehicles = [
'cars' => Array
(
'suzuki' => Array
(
'wagon' => 4,
'baleno' => 2
),
'honda' => Array
(
'civic' => 6,
'jazz' => 3
)
),
'bikes' => array
(
'raleigh' => 3,
'scott' => 1
),
'motorbikes' => Array
(
'harley-davidson' => Array
(
'dyna' => Array
(
'street-bob' => 2
)
)
)
];


So the first array adds a
$key => $value
pair where there wasn't one before. The second one replaces the value of the key at the end of
$array2
and the last one creates a new array when there isn't one to begin with.

How can I populate the array in this way?

eval()
would solve all my problems but the arrays are created from html and so it is a huge security risk.

Answer

The convenient way(on my opinion) to construct a key/value pairs list would be as the following:

// $vehicles is your initial array

$key_paths = [
  ['key_path' =>  ['cars', 'honda', 'jazz'], 'value' => 3],
  ['key_path' =>  ['bikes', 'scott'], 'value' => 1],
  ['key_path' =>  ['motorbikes', 'harley-davidson', 'dyna', 'street-bob'], 'value' => 2],
];

And here is the solution using array_slice function and references:

foreach ($key_paths as $kPath) {
    $current = null;
    foreach (array_slice($kPath['key_path'], 0, -1) as $key) {
        if (is_null($current)) {
            if (!isset($vehicles[$key])) $vehicles[$key] = [];
            $current = &$vehicles[$key];
        } else {
            if (!isset($current[$key])) $current[$key] = [];
            $current = &$current[$key];
        }
    }
    $current[end($kPath['key_path'])] = $kPath['value'];
    unset($current);    // unsetting reference
}

print_r($vehicles);

The output:

Array
(
    [cars] => Array
        (
            [suzuki] => Array
                (
                    [wagon] => 4
                    [baleno] => 2
                )

            [honda] => Array
                (
                    [civic] => 6
                    [jazz] => 3
                )
        )

    [bikes] => Array
        (
            [raleigh] => 3
            [scott] => 1
        )

    [motorbikes] => Array
        (
            [harley-davidson] => Array
                (
                    [dyna] => Array
                        (
                            [street-bob] => 2
                        )
                )
        )
)
Comments