我有一个简单的方法可以通过类中的名称访问变量:
function get_value($name) {
return isset($this->vars[$name]) ? $this->vars[$name] : NULL;
}
function set_value($name, $value) {
//Some operations with value
$this->vars[$name] = $value;
}
但我希望vars是一个多维数组。类似的东西:
//$names = array('blocks', 'top', 1)
function get_value($names) {
//Try to return $this->vars['blocks']['top'][1]
}
我可以使用像https://stackoverflow.com/a/5127874/7462321这样的循环访问值但是“set_value”代码会更加丑陋。请帮忙提出一个优雅的实现。
答案 0 :(得分:0)
这样的功能会好吗?
function get_value($arr, $keys) {
if (!is_array($keys)) {
$keys = [$keys];
}
foreach ($keys as $key) {
if (!isset($arr[$key])) {
return NULL;
}
$arr = $arr[$key];
}
return $arr;
}
这样称呼:
get_value($array, [1, 2, 3])
或:
get_value($array, 1)
答案 1 :(得分:0)
这是否符合您的需求?
我用这种方式实现了这样的事情:
<?php
class Settings {
// [...] Some stuff
/**
* Sets a value to the corresponding key
* @throws SettingsException If $key is not well written
* @param string $key The depth slahes key
* @param mixed The value to set
*/
public function setValue($key, $value){
if(strpos($key, '/') !== false){
if(($key = trim(preg_replace('#[/]+#', '/', $key), ' /')) === ''){
throw new SettingsException('"' . $key . '" is not valid');
}
$this->_setValue($key, $this->_currentGroup, $value);
} else {
$this->_currentGroup[$key] = $value;
}
$this->_saved = false;
return $this;
}
/**
* Return a setting value
* @throws SettingsException If the key doesn't exists or is null
* @param string $key The depth slashes key
* @return mixed The value corresponding to the key
*/
public function value($key){
if(strpos($key, '/')){
if(($key = trim(preg_replace('#[/]+#', '/', $key), ' /')) === ''){
throw new SettingsException('"' . $key . '" is not valid');
}
return $this->_value($key, $this->_currentGroup, $key);
} else if(isset($this->_currentGroup[$key])) {
return $this->_currentGroup[$key];
} else {
throw new SettingsException('"' . $key . '" is not a valid key');
}
}
private function _setValue($key, &$configDepth, $value){
if(($pos = strpos($key, '/'))){
if(!isset($configDepth[($k = substr($key, 0, $pos))])) {
$configDepth[$k] = array();
}
$this->_setValue(substr($key, $pos+1), $configDepth[$k], $value);
} else {
$configDepth[$key] = $value;
}
}
private function _value($key, &$configDepth, $prefix){
if(($pos = strpos($key, '/'))){
if(!isset($configDepth[($k = substr($key, 0, $pos))])) {
throw new SettingsException('The prefix "' . $prefix . '" doesn\'t exists');
}
return $this->_value(substr($key, $pos+1), $configDepth[$k], $prefix);
} else if(!isset($configDepth[$key])) {
throw new SettingsException('The prefix "' . $prefix . '" doesn\'t exists');
} else {
return $configDepth[$key];
}
}
}
设置和获取值的工作方式如上:
<?php
$s = new Settings;
$s->setValue('main/foo', 'bar'); // $s::_s[main][foo] = bar;
$main = $s->value('main'); // return Setting like an array(foo => bar);
$bar = $s->value('main/foo'); // return string value bar
//$s['main'] == $s->value('main');
// $s['main']['foo'] = 'bar' == $s->setValue('main/foo', 'bar');