too long

I can easily write to and read from a sub-array in the session array.

$_SESSION['a']['b']['c']['value']=123;
$val=$_SESSION['a']['b']['c']['value'];

Instead of hard coding the "location" where the value is written, I would like it to be definable via a string or some other way. The following will obviously not work, but hopefully will better explain the intent.

$prefix="['a']['b']['c']";  //defined in config page, etc
$_SESSION.$prefix.['value']=123;
$val=$_SESSION.$prefix.['value'];

How can this be accomplished?

PropertyAccess

There is an excellent Symfony component for such tasks, named PropertyAccess. You can use it as follows:

$persons = array('a' => array('b' => 5.7));
$accessor = PropertyAccess::createPropertyAccessor();
echo $accessor->getValue($persons, '[a][b]'); // 5.7

You can install it using Composer as described in docs or fetch directly from GitHub.

Custom solution

This is a complete solution, I'm really impressed that it works... but it works! Check the code below, assert()'s demonstrate the usage:

<?php
function arrayPropertyPathGet(array $arr, $path) {
    $parts = explode('.', $path);
    $ret = $arr;
    foreach($parts as $part) {
        $ret = $ret[$part];
        }
    return $ret;
    }

function arrayPropertyPathSet(array &$arr, $path, $value) {
    $parts = explode('.', $path);
    $tmp = &$arr;
    foreach($parts as $part) {
        if(!isset($tmp[$part])) { return false; }
        $tmp = &$tmp[$part];
        }
    $tmp = $value;
    return true;
    }

$test = array('a' => array('b' => 'value'));

assert('value' === arrayPropertyPathGet($test, 'a.b'));
assert(true === arrayPropertyPathSet($test, 'a.b', 'other'));
assert('other' === arrayPropertyPathGet($test, 'a.b'));

Side note

As a theoretical side note (do not use this for anything other than learning purposes) you can experiment with eval(), such as:

eval("$value = $persons['a']['b']");

I faced the same problem a few times ago, and as I didn't find any solution, I made one by myself, if that can help you in anyway (only the interesting part) :

class ArrayAccessor {

    private $prefix;

    function setPrefix() {
        $this->prefix = array();
        for ($i = 0; $i < func_num_args(); ++$i) {
            $this->prefix[] =  func_get_arg($i);
        }
    }

    function getFromPrefix(array $array) {
        $tmp_array = $array;
        foreach ($this->prefix as $pre) {
            if (isset ($tmp_array[$pre])) {
                $tmp_array = $tmp_array[$pre];
            } else {
                return null;
            }
        } 
        return $tmp_array;
    }

}



$Access = new ArrayAccessor();
$Access->setPrefix('Hi', 'Toto');

$MyTestArray['Hi']['Toto'] = 'Works';
var_dump ($Access->getFromPrefix($MyTestArray));

$Access->setPrefix('Hi');
var_dump ($Access->getFromPrefix($MyTestArray));

$Access->setPrefix('No');
var_dump ($Access->getFromPrefix($MyTestArray));

Result :

string(5) "Works"

array(1) {
  ["Toto"]=>
  string(5) "Works"
}

NULL