如何通过键名/路径访问和操作多维数组? [英] How to access and manipulate multi-dimensional array by key names / path?
问题描述
我必须在PHP中实现一个 setter ,它允许我指定数组(目标)的键或子键,并将名称作为点分隔键传递值.
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.
给出以下代码:
$arr = array('a' => 1,
'b' => array(
'y' => 2,
'x' => array('z' => 5, 'w' => 'abc')
),
'c' => null);
$key = 'b.x.z';
$path = explode('.', $key);
我要从$key
的值达到$arr['b']['x']['z']
的 5 值.
现在,给定变量值$key
和不同的$arr
值(深度不同).
Now, given a variable value of $key
and a different $arr
value (with different deepness).
对于 getter get()
,我编写了以下代码:
For the getter get()
I wrote this code:
public static function get($name, $default = null)
{
$setting_path = explode('.', $name);
$val = $this->settings;
foreach ($setting_path as $key) {
if(array_key_exists($key, $val)) {
$val = $val[$key];
} else {
$val = $default;
break;
}
}
return $val;
}
写一个 setter 更加困难,因为我成功地到达了正确的元素(来自$key
),但是我无法在原始数组中设置该值,所以我没有这样做.不知道如何一次指定所有按键.
To write a setter is more difficult because I succeed in reaching the right element (from the $key
), but I am not able to set the value in the original array and I don't know how to specify the keys all at once.
我应该使用某种回溯吗?还是可以避免?
Should I use some kind of backtracking? Or can I avoid it?
推荐答案
假定$path
已经是通过explode
组成的数组(或添加到函数中),则可以使用引用.您需要添加一些错误检查,以防$path
等无效(请考虑isset
):
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
设置者/创建者
如果您传递的数组尚未定义,则此组合将在现有数组中设置一个值或创建该数组.确保定义$array
以通过引用&$array
传递:
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');
取消设置
这将unset
路径中的最终键:
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);
*如果原始答案对某人有用,我将保留一些有限的功能:
设置
确保定义$array
以通过引用&$array
传递:
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');
创作者
如果您不想创建数组并选择设置值:
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');
为了娱乐
在给定字符串b.x.z
的情况下,构造并评估类似$array['b']['x']['z']
的内容:
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;
}
设置类似$array['b']['x']['z'] = 'some value';
的内容:
function set(&$array, $path, $value) {
//$path = explode('.', $path); //if needed
$path = "['" . implode("']['", $path) . "']";
eval("\$array{$path} = $value;");
}
取消类似$array['b']['x']['z']
的设置:
function unsetter(&$array, $path) {
//$path = explode('.', $path); //if needed
$path = "['" . implode("']['", $path) . "']";
eval("unset(\$array{$path});");
}
这篇关于如何通过键名/路径访问和操作多维数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!