PHP insert value to a multidimensional array based on dynamic sequence of keys

We know how to access PHP array items. If we know the number of keys and name of keys we can set a value to a multidimensional array item.
For example : $arr[‘a’][‘b’][‘c’] = ‘my value’.
Array keys can be stored in variable.
For example :

$key1 = 'a'; $key2 = 'b'; $key3 = 'c';
$arr[$key1][$key2][$key3] = 'my value';


In this example our array keys are known. And it is very easy to write code. But problem is when our keys are variable and you don’t know how many are they , then we can not write a single line of code to access the item. If I give you the array keys in an array where a key is the parent of next key then how do you write the code.
For example : I have an array

$arr = array(
    'a' => array(
        'b' => array(
            'c'=>100,
        )
    ),
    'x' => array(),
);


And key list in sequence

$keys = array('a', 'b','c');


The goal is to change the value 100 to a new value 500. You have to write a code that is equivalent to following code

$arr['a']['b']['c'] = '500';


I don’t know any PHP syntax to do this. You can try using PHP variable variables rule. But that will not work.
I have written a function to solve the problem.

/**
 * Insert new item to a multidimensional array where sequence of keys are stored in an array.
 * @param array() $arr . Array where the value will be inserted. This array can be empty.
 * @param array() $key_chain. Array of keys where a key is the parent of the next key. Keys can be number, string or event BLANK string.
 * @param mixed $value. The value that you want to insert to the array.
 * @return bool. True for success and false for fail.
 */
function insert_into_array_by_key_chain(&$arr, $key_chain, $value )
{
    if( !is_array( $key_chain ) || count( $key_chain ) == 0 ){ return false; }
 
    $ref = &$arr;//take the reference of the array.
    foreach( $key_chain as $key )
    {
        $key = trim( $key );
        if( $key == '')
        {
            $ref[] = array();        //Just a fake value. This will be overridden on next cycle or after the loop. This fake value must be an array to avoid error for next valid non blank key.
            end($ref);               //set the internal pointer of array to the last item.
            $ref = &$ref[key($ref)]; //take the reference of the last inserted fake item. Function key() returns the key of current item of the array. In this case it is last item.
        }
        else
        {
            $ref = &$ref[$key];     //take the new reference of the item of child array based on the key from the current reference.
        }
 
    }
    $ref = $value; //Assign the value to the calculated reference.
    unset($ref);//must unset the $ref , otherwise it can produce unpredictable results. See the example here http://php.net/manual/en/language.references.php#83325
    return true;
}

Example Usages :

$arr = array(
    'a' => array(
        'b' => array(
            'c' => 100,
        )
    ),
    'x' => array(),
);
$keys = array('a', 'b','c');
 
insert_into_array_by_key_chain($arr, $keys, 500 );
$keys = array('a', 'b','d');
insert_into_array_by_key_chain($arr, $keys, 600 );
$keys = array('a', 'b','e','');
insert_into_array_by_key_chain($arr, $keys, 'hello' );
insert_into_array_by_key_chain($arr, $keys, 'world' );


OUTPUT :

Array
(
    [a] => Array
        (
            [b] => Array
                (
                    ['c'] => 500
                    [d] => 600
                    [e] => Array
                        (
                            [0] => hello
                            [1] => world
                        )
  
                )
  
        )
  
    [x] => Array
        (
        )
  
)

Leave a Reply

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.