有没有办法动态访问多维 PHP 数组?

Is there a way to dynamically access multidimensional PHP array?

有没有办法动态访问 PHP 多维数组(特定索引)?

例如,假设我想访问一个值:

$array[1]['children'][0]['children'][2]['settings']['price']

是否可以有一个函数通过获取索引(分别为 1、0 和 2)来 returns 这个值?并且无论是否有 3 个值(1、0 和 2)或更多,它都会起作用。

例如,我们调用函数“getArrayValue()”,我们可以这样调用:

getArrayValue('1,0,2')

这应该return $array[1]['children'][0]['children'][2]['country']['city']

或者如果有 2 个值 getArrayValue('1,0') 应该 return $array[1]['children'][0]['country']['city']

所以基本上,我面临的问题是需要帮助动态构建查询以获取数组值...

是否有办法转换像$array[1]['children'][0]['country']['city']这样的字符串并评估它以从数组本身获取这个值?

另一种解释我的问题的方式:

$arrayIndex = "[1]['children'][0]";
$requiredValue = $array[1] . $arrayIndex . ['country']['city'];

//// so $requiredValue should output the same value as the below line would:
$array[1]['children'][0]['children'][2]['country']['city'];

有办法实现吗?

在你的情况下,你需要这样的东西:

<?php
  

function getArray($i, $j, $k, $array) {
    if (isset($array[$i]['children'][$j]['children'][$k]['country']['city']))
    {
        return $array[$i]['children'][$j]['children'][$k]['country']['city'];
    }
}

$array[0]['children'][0]['children'][0]['country']['city'] = "some value";
$array[0]['children'][0]['children'][1]['country']['city'] = "another";
$array[0]['children'][1]['children'][1]['country']['city'] = "another one";
.
.
.
etc


echo getArray(0,0,0, $array) . "\n"; // output -> "some value"
echo getArray(0,0,1, $array) . "\n"; // output -> "another"
echo getArray(0,1,1, $array) . "\n"; // output -> "another one"

另一件要记住的事情是你调用了只传递一个参数的函数。而你的多维数组至少需要三个。

getArrayValue('1,0,2')

您必须考虑到您调用的函数只传递了一个参数。即使有逗号。但它实际上是一个字符串。

getArrayValue(1,0,2) //not getArrayValue('1,0,2') == string 1,0,2

如果你想传递两个值,你必须至少放一个 if 来控制你希望函数在这种情况下执行什么。类似于:

  function getArray($i, $j, $k, $array) {
    if($k==null){
        if(isset($array[$i]['children'][$j]['country']['city'])){
            return $array[$i]['children'][$j]['country']['city']; //
        }
    } else {
        if(isset($array[%i]['children'][$j]['children'][$k]['country']['city'])){
            return $array[$i]['children'][$j]['children'][$k]['country']['city'];
        }
    }
}

getArray(0,0,null, $array) 
getArray(0,0,1, $array) 

最后一题可以通过eval()函数得到。但我认为这不是一个好主意。至少不推荐。示例:

echo ' someString ' . eval( 'echo $var = 15;' );

可以查看文档:https://www.php.net/manual/es/function.eval.php

编辑: 我忘了提你也可以使用默认参数。喜欢这里。

<?php

$array[0]['children'][0]['children'][0]['country']['city'] = "some value";
$array[0]['children'][0]['children'][1]['country']['city'] = "another";
$array[0]['children'][1]['children'][1]['country']['city'] = "another one";

function getArray($array,$i, $j, $k = null) {
    if($k==null){
        echo 'getArray called without $k argument';
        echo "\n";
    } 
    else{
        echo 'getArray called with $k argument';
        echo "\n";
    }
   
}

getArray($array,0,0);    //here you call the function with only 3 arguments, instead of 4
getArray($array,0,0,1);

在这种情况下,$k 是可选的。如果省略它,则默认值为空。此外,您还必须考虑到函数可以使用类似于分配变量的语法为参数定义默认值。仅在未指定参数时使用默认值;特别注意,传递 null 不会分配默认值。

<?php
function makecoffee($type = "cappuccino"){
    return "Making a cup of $type.\n";
}
echo makecoffee();
echo makecoffee(null);
echo makecoffee("espresso");

上面的例子会输出:

Making a cup of cappuccino.
Making a cup of .
Making a cup of espresso.

您可以在此处阅读更多相关信息:https://www.php.net/manual/en/functions.arguments.php

我发现@Dac2020 的回答过于死板,对未来的研究人员没有帮助。事实上,问题中过多的 specific/niche 要求并不能使该页面对未来的研究人员有很大帮助,因为处理逻辑与数组结构紧密耦合。

就是说,我已经尝试设计一个函数来构建检查密钥和 D.R.Y 是否存在的最佳实践。希望未来的研究人员能够根据自己的需要轻松修改它。

在自定义函数中,第一步是将 csv 拆分为一个数组,然后按照提问者的指示将静态键交织在动态键之间。在更一般的用例中,所有键都将传递到函数中,从而无需准备键数组。

正如@MarkusAO 在问题下的评论中正确提到的那样,这个问题几乎与 Convert dot syntax like "this.that.other" to multi-dimensional array in PHP.

重复

代码:(Demo)

function getValue($haystack, $indexes) {
    $indices = explode(',', $indexes);
    $finalIndex = array_pop($indices);
    $keys = [];
    foreach ($indices as $keys[]) {
        $keys[] = 'children';
    }
    array_push($keys, $finalIndex, 'country', 'city');
    //var_export($keys);

    foreach ($keys as $level => $key) {
        if (!key_exists($key, $haystack)) {
            throw new Exception(
                sprintf(
                    "Path attempt failed for [%s]. No `%s` key found on levelIndex %d",
                    implode('][', $keys),
                    $key,
                    $level
                )
            );
        }
        $haystack = $haystack[$key];
    }
    return $haystack;
}

$test = [
    [
        'children' => [
            [
                'children' => [
                    [
                        'country' => [
                            'city' => 'Paris',
                         ]
                    ],
                    [
                        'country' => [
                            'city' => 'Kyiv',
                         ]
                    ]
                ]
            ]
        ]
    ],
    [
        'children' => [
            [
                'country' => [
                    'city' => 'New York',
                ]
            ],
            [
                'country' => [
                    'city' => 'Sydney',
                ]
            ]
        ]
    ]
];

$result = [];
try {
    $result['0,0,0'] = getValue($test, '0,0,0');
    $result['1,0'] = getValue($test, '1,0');
    $result['1,0,0'] = getValue($test, '1,0,0');
} catch (Exception $e) {
    echo $e->getMessage() . "\n---\n";
}
var_export($result);

输出:

Path attempt failed for [1][children][0][children][0][country][city]. No `children` key found on levelIndex 3
---
array (
  '0,0,0' => 'Paris',
  '1,0' => 'New York',
)