Xees Xees - 28 days ago 6
PHP Question

Get a value from a multidimensional array using the dot syntax

I have the following array:

$conf = array(
'db' => array(
'server' => 'localhost',
'user' => 'root',
'pass' => 'root',
'name' => 'db',
),
'path' => array(
'site_url' => $_SERVER['SERVER_NAME'],
'site_dir' => CMS,
'admin_url' => conf('path.site_url') . '/admin',
'admin_dir' => conf('path.site_dir') . DS .'admin',
'admin_paths' => array(
'assets' => 'path'
),
),
);


I would like to get a value from this array using a function like so:

/**
* Return or set a configuration setting from the array.
* @example
* conf('db.server') => $conf['db']['server']
*
* @param string $section the section to return the setting from.
* @param string $setting the setting name to return.
* @return mixed the value of the setting returned.
*/
function conf($path, $value = null) {
global $conf;
// We split each word seperated by a dot character
$paths = explode('.', $path);

return $conf[$paths[0]][$paths[1]];
}


But i would like it if the function resolves all dimensions of the array and not just the first two.

Like this

conf('path.admin_paths.assets');


would resolve to

=> $conf['path']['admin_paths']['assets']


How would i do this? Also, how would i make this function if it has another param, would set a value rather than return it?

Answer

I found @Danijel recursive approach a lot cleaner than my initial try. So here's a recursive implementation of the functionality, supporting setting values.

function array_get_by_key(&$array, $key, $value = null) {
    list($index, $key) = explode('.', $key, 2);
    if (!isset($array[$index])) throw new Exception("No such key: " . $index);

    if(strlen($key) > 0)
        return array_get_by_key(&$array[$index], $key, $value);

    $old = $array[$index];
    if ($value !== null) $array[$index] = $value;
    return $old;    
}

function config($key, $value = null) {
    global $CONFIG;
    return array_get_by_key(&$CONFIG, $key, $value);
}

Test run:

$CONFIG = array(
'db'    => array(
    'server'    =>  'localhost',
    'user'      =>  'root',
    'pass'      =>  'root',
    'name'      =>  'db',
    ),
'path'  =>  array(
    'site_url'  =>  'localhost',
    'site_dir'  => 'CMS',
    'admin_url' => 'localhost/admin',
    'admin_dir' => 'localhost/res/admin',
    'admin_paths' => array(
                'assets' => 'path'
                ),
    ),
);

try {
    var_dump(config('db.pass'));
    var_dump(config('path.admin_url', 'localhost/master'));
    var_dump(config('path.admin_url'));
    var_dump(config('path.no_such'));
} catch (Exception $e) {
    echo "Error: trying to access unknown config";
}

// string(4) "root"
// string(15) "localhost/admin"
// string(16) "localhost/master"
// Error: trying to access unknown config