当前位置: 首页 > 知识库问答 >
问题:

如何通过键名/路径访问和操作多维数组?

胡翔
2023-03-14

我必须在PHP中实现一个setter,它允许我指定一个数组(目标)的键或子键,并以点分隔键值的形式传递名称。

给定以下代码:

$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值(具有不同的深度)。

对于getterget()我编写了以下代码:

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)找到了正确的元素,但我无法在原始数组中设置值,也不知道如何同时指定所有键。

我应该使用某种回溯吗?或者我可以避开它?

共有1个答案

丁兴德
2023-03-14

假设$path已经是通过explorde(或添加到函数)创建的数组,那么您可以使用引用。您需要在$PATH等无效的情况下添加一些错误检查(请考虑isset):

$key = 'b.x.z';
$path = explode('.', $key);
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:

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

这将取消设置路径中的最后一个键:

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:

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

或者如果您想返回更新后的数组(因为我很无聊):

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

创建者

如果您不想创建数组并可选地设置值:

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

为了好玩

构造并计算类似$array['b']['x']['z']的值,给定字符串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});");
}
 类似资料:
  • 问题内容: 我必须在PHP中实现一个 setter ,它允许我指定数组(目标)的键或子键,并将名称作为点分隔键值传递。 给出以下代码: 从价值我想达到的值 5 的。 现在,给定变量值和不同的值(深度不同)。 如何设置by引用的元素的值? 对于 getter, 我编写了以下代码: 写一个 setter 比较困难,因为我成功地从到达了正确的元素,但是我无法在原始数组中设置值,而且我也不知道如何一次全部

  • 我正在用Extbase构建一个TYPO3扩展,并希望存储通过httpget获取的数据。现在我正在努力使用浏览器访问动作控制器。 插件被实现到第102页 扩展键是xyzlist 插件名称是xyzlistdb 控制器名称是playlicontroller 操作是getAction 域名是sub.domain。de 在播放控制器中。php仅在getAction下 错误日志(“getAction”,0)

  • 问题内容: 我试图通过多个键对多维数组进行排序,但我不知道从哪里开始。我看了uasort,但不确定如何根据需要编写函数。 我需要按状态排序,然后按event_type排序,然后按日期排序。 我的数组如下所示: 问题答案: 你需要 从PHP 5.5.0开始: 就是现在:

  • 问题内容: 我一直在使用Serialize()将复选框形式的数据与Post()传递给可以容纳多个相同类别项目的购物篮。 当我使用“提交”按钮发布它们时,它可以很好地工作,并且可以将多个值传递并显示在一个类别下。 但是,当我使用Jquery serialize()时,每个类别仅显示一个项目,而总共仅显示两个类别。这是一个阵列问题,但我无法解决。 我应该使用替代的JQuery函数来传递多维数组吗? 问

  • 问题 你需要使用路径名来获取文件名,目录名,绝对路径等等。 解决方案 使用 os.path 模块中的函数来操作路径名。 下面是一个交互式例子来演示一些关键的特性: >>> import os >>> path = '/Users/beazley/Data/data.csv' >>> # Get the last component of the path >>> os.path.basename

  • 问题内容: 基本上我需要做的是 我尝试做明显的 但这最终会引发异常 即使在互操作文档中为访问静态字段指定的表示法也会产生相同的异常 问题答案: 您可以使用$访问内部类 请注意,如果要导入,也应该导入。