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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.