如何用单个字符串替换嵌套或多级数组的选择器

问题描述 投票:0回答:2

我正在尝试用PHP中的单个字符串替换多级数组选择器。我尝试过的下面的代码是在PHP 7.2中运行的。

1.

$nested_array_selectors = '"my_array"]["my_key"]["my_elemnt"';
var_dump($my_instance->my_object[$nested_array_selectors]);

2.

$nested_array_selectors = 'my_array"]["my_key"]["my_elemnt';
var_dump($my_instance->my_object["$nested_array_selectors"]);

3.

$nested_array_selectors = '["my_array"]["my_key"]["my_elemnt"]';
var_dump($my_instance->my_object$nested_array_selectors);

我希望$ nested_array_selectors可以作为$my_instance->my_object["my_array"]["my_key"]["my_element"];工作,但1和2返回“null”,3得到Parse error(当然)。

它实际上是不可能的还是有人能告诉我如何解决它?

php arrays string drupal syntax
2个回答
0
投票

像这样的东西

$selectors = ["my_array","my_key","my_elemnt"];

$data = (array)$my_instance->my_object;

foreach($selectors as $k=>$v){
    if(isset($data[$k])){
        $data = $data[$k]; //reduce data by 1 level
    }else{
       $data = false;
       break;
    }
}

print_r($data);

基本上每次循环遍历数组中存在的“选择器”时,将数组减少1级,例如,如果我们从这开始

$data = ['foo'=>['bar'=>['baz'=>1]]];
$selectors = ["foo","bar","baz"];

foreach($selectors as $v){
    print_r($data);
    if(isset($data[$v])){
        $data = $data[$v]; //reduce data by 1 level
    }else{
       $data = false;
       break;
    }
}
echo "\n---------- Final ------------\n";
print_r($data);

产量

Array
(
    [foo] => Array
        (
            [bar] => Array
                (
                    [baz] => 1
                )

        )

)
Array
(
    [bar] => Array
        (
            [baz] => 1
        )

)
Array
(
    [baz] => 1
)

---------- Final ------------
1

Sandbox

您可以在上面看到“插图”,了解我们如何深入了解我们想要的元素。上面的每个array都是$data的状态,然后通过选择器级别降低它。所以之后的那个显示了减少它的结果。所以第一个数组是在应用"foo"之前,第二个数组是在那之后,但在"bar"等之前......

如果你想使用$selectors的字符串,比如逗号或其他什么,那么使用explode()preg_split()将某个分隔符上的字符串分解为数组就是一个简单的问题。例如:

 $selectors = "foo.bar.baz";
 $selectors = explode(".", $selectors ); //["foo","bar","baz"]
 //...

PS我会使用它提供的实际数据,但因为这是我测试它的唯一方法解释它。

此外,这显然是一个很好的候选者来制作一个功能:

function transverseWithKeys(array $array, $keys, $default=null, $glue='.'){
   if(!is_array($keys)) $keys = explode($glue,$keys);

   foreach($keys as $v){
       if(isset($array[$v])){
           $array= $array[$v]; //reduce data by 1 level
       }else{
           return $default;
       }
   }
   return $array;
}

希望能帮助到你。


0
投票

您尝试执行的操作无效,因为您尝试将变量转换为PHP代码。 PHP不知道这是你的意图,并没有执行该代码。

PHP确实有一个eval()结构,可以让你这样做。

注意eval()语言结构非常危险,因为它允许执行任意PHP代码。因此不鼓励使用它。如果您已仔细验证除了使用此构造之外没有其他选项,请特别注意不要将任何用户提供的数据传递到其中,而不事先正确验证它。

PHP manual for eval解释更多。

将字符串评估为PHP代码

在您的情况下,以下代码将起作用。

$nested_array_selectors = '["my_array"]["my_key"]["my_elemnt"]';
eval('var_dump($my_instance->my_object' . $nested_array_selectors . ')');
© www.soinside.com 2019 - 2024. All rights reserved.