1
\$\begingroup\$

I have an object which stores an app configuration in an associative array, as this:

[
  'Database' => 
    [
      'DB_SERVER' => 'localhost'
      'DB_NAME' => 'adbname'
      'DB_USER' => 'theuser'
      'DB_PASS' => 'thepass'
    ]
]

And a function, get(), which receives a variable number of arguments and returns the configuration value for this parameters. For example, Config::get('Database','DB_PASS') will return 'thepass'.

This is an excerpt of the code:

class Config
{
    protected static $values;

    ...

    public static function get()
    {
        $val = &self::$values;
        $argList = func_get_args();
        for ($i = 0; $i < count($argList); $i++) {
            $val = &$val[$argList[$i]];
            if(empty($val)) break;
        }
        return (is_null($val)?"":$val);
    }
}

Is there a more elegant / efficient way of accessing the value?

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

This seems alright, but you could use foreach, and checking and returning can be simpler:

class Config
{
    protected static $values;

    ...

    public static function get()
    {
        $val = &self::$values;
        foreach(func_get_args() as $argument)
        {  
          $val = &$val[$argument];
          if(empty($val)) return "";
        }
        return $val;
    }
}

I would call this more elegant, but it's not more efficient. (I did not test the code.)

\$\endgroup\$
2
  • \$\begingroup\$ I didn't have the courage to use foreach: iteration throught arrays seems to be tricky, and I wanted to be sure that the processing order was the same. \$\endgroup\$ Commented Jun 8, 2016 at 13:24
  • \$\begingroup\$ It will most likely work, foreach simply starts with the first element, and then the next, just like your for loop. \$\endgroup\$ Commented Jun 8, 2016 at 15:08
1
\$\begingroup\$

There is more accurate and efficient way to access config options:

class Config {

    protected static $values = [    // exemplary config array
        'Database' =>
                [
                    'DB_SERVER' => 'localhost',
                    'DB_NAME' => 'adbname',
                    'DB_USER' => 'theuser',
                    'DB_PASS' => 'thepass'
                ],
        'testUrl' => "http://myexample.com"     // 1st level option
    ];

    public static function get() {
        $args = func_get_args();
        $count = count($args);

        if ($count == 0 || empty($args[0])) {
            throw new \Exception("Unspecified config option!");
        }
        if ($count == 1 && isset(self::$values[$args[0]])) {
            return self::$values[$args[0]];
        } elseif ($count == 2 && isset(self::$values[$args[0]])
                && is_array(self::$values[$args[0]]) 
                && isset(self::$values[$args[0]][$args[1]])) {
            return self::$values[$args[0]][$args[1]];
        }

        return null;
    }
}

print_r(Config::get('Database','DB_PASS'));  // "thepass"
print_r(Config::get('testUrl'));             // "http://myexample.com"
print_r(Config::get(""));              // will throw an exception: Unspecified config option!
\$\endgroup\$
4
  • \$\begingroup\$ But what if we have more than two levels? I wouldn't work... \$\endgroup\$ Commented Jun 8, 2016 at 13:19
  • \$\begingroup\$ @AlvaroMaceda so, you should know how deep can be your config path \$\endgroup\$ Commented Jun 8, 2016 at 13:30
  • \$\begingroup\$ Let's say I have ten levels. \$\endgroup\$ Commented Jun 8, 2016 at 19:24
  • \$\begingroup\$ @AlvaroMaceda, ten levels? That's bad practice to construct a tangled/confused structure for intensively used config within application \$\endgroup\$ Commented Jun 8, 2016 at 20:23

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.