6

In relation to this question i asked earlier: Searching multi-dimensional array's keys using a another array

I'd like a way to set a value in a multi-dimensional array (up to 6 levels deep), using a seperate array containing the keys to use.

e.g.

$keys = Array ('A', 'A2', 'A22', 'A221');
$cats[A][A2][A22][A221] = $val;

I tried writing a clumsy switch with little success... is there a better solution?

function set_catid(&$cats, $keys, $val) {
    switch (count($keys)) {
        case 1: $cats[$keys[0]]=$val; break;
        case 2: $cats[$keys[0]][$keys[1]]=$val; break;
        case 3: $cats[$keys[0]][$keys[1]][$keys[2]]=$val; break;
        etc...
    }
}
1
  • You could use references to traverse the array by any number of keys. Commented Nov 24, 2011 at 21:32

3 Answers 3

1

try this:

function set_catid(&$cats, $keys, $val) {
  $ref =& $cats;
  foreach ($keys as $key) {
    if (!is_array($ref[$key])) {
      $ref[$key] = array();
    }
    $ref =& $ref[$key];
  }
  $ref = $val;
}
Sign up to request clarification or add additional context in comments.

4 Comments

This works great unless the final key doesn't exist, which in my case it won't. i get the error "Fatal error: Cannot create references to/from string offsets nor overloaded objects" on $ref =& $ref[$key]; how would i resolve this?
weird. that works well for me. (starting with a totally empty array $cats) .. must be because "A22" (the key before last key) exist as something different which is not an array. e.g. string? in that case replacing isset() with is_array() will help -- but you will lose the string in "A22" by replacing it with another array.. can you post output of print_r($cats) before using this function?
i made the change i suggested in the example, try again
fantastic! ...i've been trying loads of data combinations, but couldn't work out a pattern. using is_array has fixed it. many thanks.
1
function insertValueByPath($array, $path, $value) {
    $current = &$array;
    foreach (explode('/', $path) as $part) {
        $current = &$current[$part];
    }
    $current = $value;

    return $array;
}

$array = insertValueByPath($array, 'A/B/C', 'D');
// => $array['A']['B']['C'] = 'D';

You can obviously also use an array for $path by just dropping the explode call.

Comments

0

You should use references.

In the foreach we're moving deeper from key to key. Var $temp is reference to current element of array $cat. In the end temp is element that we need.

   <?php

    function set_catid(&$cats, $keys, $val) {
        $temp = &$cats;
        foreach($keys as $key) {
            $temp = &$temp[$key];
        }

        $temp = $val;
    }

    $cats = array();
    $keys = Array ('A', 'A2', 'A22', 'A221');
    set_catid($cats, $keys, 'test');
    print_r($cats);
    ?>

1 Comment

That works great unless the final key doesn't exist, which in my case it won't. so i'll need to add a new key and value pair. how would i do that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.