Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a value from a multidimensional array using the dot syntax

Tags:

arrays

php

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?

like image 846
Xees Avatar asked Feb 18 '26 16:02

Xees


2 Answers

This function works:

function conf($path, $value = null) {
    global $conf;
    // We split each word seperated by a dot character
    $paths = explode('.', $path);
    $result = $conf;
    foreach ($paths as $path) {
        $result = $result[$path];
    }
    return $result;
}

Edit:

Add Set:

function conf($path, $value = null) {
    global $conf;
    // We split each word seperated by a dot character
    $paths = explode('.', $path);
    if ($value === null) {
        // Get
        $result = $conf;
        foreach ($paths as $path) {
            $result = $result[$path];
        }
        return $result;
    }
    // Set
    if (!isset($conf)) $conf = array(); // Initialize array if $conf not set
    $result = &$conf;
    foreach ($paths as $i=>$path) {
        if ($i < count($paths)-1) {
            if (!isset($result[$path])) {
                $result[$path] = array();
            }
            $result = &$result[$path];
        } else {
            $result[$path] = $value;
        }
    }
}
like image 100
gabrieloliveira Avatar answered Feb 21 '26 14:02

gabrieloliveira


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
like image 23
svvac Avatar answered Feb 21 '26 14:02

svvac



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!