How to access and manipulate multi-dimensional array by key names / path?

前端 未结 10 2198
北恋
北恋 2020-11-21 07:35

I\'ve to implement a setter in PHP, that allows me to specify the key, or sub key, of an array (the target), passing the name as a dot-separated-keys value.

10条回答
  •  离开以前
    2020-11-21 07:51

    Assuming $path is already an array via explode (or add to the function), then you can use references. You need to add in some error checking in case of invalid $path etc. (think isset):

    $key = 'b.x.z';
    $path = explode('.', $key);
    

    Getter

    function get($path, $array) {
        //$path = explode('.', $path); //if needed
        $temp =& $array;
    
        foreach($path as $key) {
            $temp =& $temp[$key];
        }
        return $temp;
    }
    
    $value = get($path, $arr); //returns NULL if the path doesn't exist
    

    Setter / Creator

    This combination will set a value in an existing array or create the array if you pass one that has not yet been defined. Make sure to define $array to be passed by reference &$array:

    function set($path, &$array=array(), $value=null) {
        //$path = explode('.', $path); //if needed
        $temp =& $array;
    
        foreach($path as $key) {
            $temp =& $temp[$key];
        }
        $temp = $value;
    }
    
    set($path, $arr);
    //or
    set($path, $arr, 'some value');
    

    Unsetter

    This will unset the final key in the path:

    function unsetter($path, &$array) {
        //$path = explode('.', $path); //if needed
        $temp =& $array;
    
        foreach($path as $key) {
            if(!is_array($temp[$key])) {
                unset($temp[$key]);
            } else {
                $temp =& $temp[$key];
            }
        }
    }
    unsetter($path, $arr);
    

    *The original answer had some limited functions that I will leave in case they are of use to someone:

    Setter

    Make sure to define $array to be passed by reference &$array:

    function set(&$array, $path, $value) {
        //$path = explode('.', $path); //if needed
        $temp =& $array;
    
        foreach($path as $key) {
            $temp =& $temp[$key];
        }
        $temp = $value;
    }
    
    set($arr, $path, 'some value');
    

    Or if you want to return the updated array (because I'm bored):

    function set($array, $path, $value) {
        //$path = explode('.', $path); //if needed
        $temp =& $array;
    
        foreach($path as $key) {
            $temp =& $temp[$key];
        }
        $temp = $value;
    
        return $array;
    }
    
    $arr = set($arr, $path, 'some value');
    

    Creator

    If you wan't to create the array and optionally set the value:

    function create($path, $value=null) {
        //$path = explode('.', $path); //if needed
        foreach(array_reverse($path) as $key) {
            $value = array($key => $value);
        }
        return $value;
    }    
    
    $arr = create($path);    
    //or
    $arr = create($path, 'some value');
    

    For Fun

    Constructs and evaluates something like $array['b']['x']['z'] given a string b.x.z:

    function get($array, $path) {
        //$path = explode('.', $path); //if needed
        $path = "['" . implode("']['", $path) . "']";
        eval("\$result = \$array{$path};");
    
        return $result;
    }
    

    Sets something like $array['b']['x']['z'] = 'some value';:

    function set(&$array, $path, $value) {
        //$path = explode('.', $path); //if needed
        $path = "['" . implode("']['", $path) . "']";
        eval("\$array{$path} = $value;");
    }
    

    Unsets something like $array['b']['x']['z']:

    function unsetter(&$array, $path) {
        //$path = explode('.', $path); //if needed
        $path = "['" . implode("']['", $path) . "']";
        eval("unset(\$array{$path});");
    }
    

提交回复
热议问题