我正在尝试用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
(当然)。
实际上是不可能的,还是有人可以告诉我如何解决?
答案 0 :(得分: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 . ')');
答案 1 :(得分: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
您可以在上方看到“插图”,可以深入了解所需的元素。上面的每个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;
}
希望有帮助。