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?
2 Answers 2
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.)
-
\$\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\$Alvaro Maceda– Alvaro Maceda2016年06月08日 13:24:56 +00:00Commented 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 yourfor
loop. \$\endgroup\$KIKO Software– KIKO Software2016年06月08日 15:08:13 +00:00Commented Jun 8, 2016 at 15:08
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!
-
\$\begingroup\$ But what if we have more than two levels? I wouldn't work... \$\endgroup\$Alvaro Maceda– Alvaro Maceda2016年06月08日 13:19:21 +00:00Commented Jun 8, 2016 at 13:19
-
\$\begingroup\$ @AlvaroMaceda so, you should know how deep can be your config path \$\endgroup\$RomanPerekhrest– RomanPerekhrest2016年06月08日 13:30:08 +00:00Commented Jun 8, 2016 at 13:30
-
\$\begingroup\$ Let's say I have ten levels. \$\endgroup\$Alvaro Maceda– Alvaro Maceda2016年06月08日 19:24:40 +00:00Commented 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\$RomanPerekhrest– RomanPerekhrest2016年06月08日 20:23:48 +00:00Commented Jun 8, 2016 at 20:23