6

Assume I have the following function

function setArray(&$array, $key, $value)
{
    $array[$key] = $value;     
}

In the above function, key is only at the first level, what if I want to set the key at the 2nd or 3rd levels, how to rewrite the function?

e.g.

 $array['foo']['bar'] = 'test';

I want to use the same function to set the array value

Ryan
  • 10,041
  • 27
  • 91
  • 156

5 Answers5

15

This one should work. Using this function you can set any array element in any depth by passing a single string containing the keys separated by .

function setArray(&$array, $keys, $value) {
  $keys = explode(".", $keys);
  $current = &$array;
  foreach($keys as $key) {
    $current = &$current[$key];
  }
  $current = $value;
}

You can use this as follows:

$array = Array();
setArray($array, "key", Array('value' => 2));
setArray($array, "key.test.value", 3);
print_r($array);

output:

Array (
    [key] => Array
        (
            [value] => 2
            [test] => Array
                (
                    [value] => 3
                )

        )

)
MarcDefiant
  • 6,649
  • 6
  • 29
  • 49
  • 1
    The isset() part is unnecessary, as PHP will create both the slot and the empty array automatically when you make the reference. – cleong Nov 13 '12 at 11:30
  • Hey @MarcDefiant - any idea if this works well with php since 'by reference' has been deprecated? – craigh Dec 12 '16 at 19:58
  • 1
    It's EXACTLY what I needed, thanks. (been struggling for 30 minutes to come up with something like this...) – Radu Murzea Nov 24 '17 at 10:04
  • @craigh calling by reference was deprecated. Not creating function by reference. – Gall Annonim Jul 26 '19 at 09:12
1

You can use array_merge_recursive

$array = array("A" => "B");
$new['foo']['bar'] = 'test';
setArray($array, $new);
var_dump($array);

Output

array (size=2)
  'A' => string 'B' (length=1)
  'foo' => 
    array (size=1)
      'bar' => string 'test' (length=4)

Function Used

function setArray(&$array, $value) {
    $array = array_merge_recursive($array, $value);
}
Baba
  • 94,024
  • 28
  • 166
  • 217
1

this function should do it, the key should be an array, for example array('foo', 'bar')

function setArray(&$array, array $keys, $value) {
  foreach($keys as $key) {
    if(!isset($array[$key])) {
      $array[$key] = array();
    }
    $array = &$array[$key];
  }
  $array = $value;
}

$arr = array();
setArray($arr, array('first', 'second'), 1);
var_dump($arr);
// dumps array(1) { ["first"]=> array(1) { ["second"]=> int(1) } } 

Tested and works.

pocesar
  • 6,860
  • 6
  • 56
  • 88
0

Use array_replace_recursive instead of array_merge_recursive as it handles same-key scenario correctly. See this https://3v4l.org/2ICmo

Tomáš Fejfar
  • 11,129
  • 8
  • 54
  • 82
-1

Just like this:

function setArray(&$array, $key1, $key2, $value)
{
    $array[$key1][$key2] = $value;     
}

But why you want to use function? Using it like this:

setArray($array, 'foo', 'bar', 'test');

takes more time to write something like this:

$array[1][2] = 'test';
Kamil
  • 13,363
  • 24
  • 88
  • 183