通过PHP中的键列表获取数组的值

时间:2017-02-02 09:46:27

标签: php arrays

我有一个简单的方法可以通过类中的名称访问变量:

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”代码会更加丑陋。请帮忙提出一个优雅的实现。

2 个答案:

答案 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');