PHP中如何通过字符串形式的数组键路径查找数组值?
嘿,这个需求我之前也碰到过,给你几个实用的解决方案,你可以根据自己的场景来选:
解决方案1:手动解析路径字符串(安全可靠,推荐)
这种方法会先把你的路径字符串解析成键数组,再逐层遍历原数组取值,完全避免了代码注入风险,适合大多数场景。
function getArrayValueByPath(array $array, string $path) { // 用正则提取路径里的所有键 preg_match_all("/\['(.*?)'\]/", $path, $matches); $keys = $matches[1]; $currentValue = $array; foreach ($keys as $key) { // 如果某个键不存在,可以返回null或者抛出异常,按需调整 if (!isset($currentValue[$key])) { return null; } $currentValue = $currentValue[$key]; } return $currentValue; } // 测试你的示例 $test = ['test','test2' => ['test3','test4' => ['test5']]]; $pattern = "['test2']['test4']"; print_r(getArrayValueByPath($test, $pattern)); // 输出:Array ( [0] => test5 )
说明
- 正则
/\['(.*?)'\]/会匹配所有['xxx']格式的片段,提取出里面的键名 - 遍历键数组逐层访问,每一步都做存在性检查,避免报错
- 完全安全,哪怕路径来自用户输入也不用担心代码注入
解决方案2:使用eval(简洁但需谨慎)
如果你的路径字符串是完全可控的(比如自己生成的,不是用户输入的),可以用eval直接实现你想要的$test{$pattern}类似效果,代码最简洁:
$test = ['test','test2' => ['test3','test4' => ['test5']]]; $pattern = "['test2']['test4']"; // 构造eval语句,注意变量名的转义 eval("\$result = \$test{$pattern};"); print_r($result); // 输出:Array ( [0] => test5 )
重要提醒
**这个方法绝对不能用于不可信的路径输入!**如果有人恶意传入类似['test2']); phpinfo(); //的路径字符串,eval会执行里面的恶意代码,导致安全问题。只有在你能100%保证路径安全的场景下才用这个方法。
解决方案3:自定义可路径访问的数组类(优雅语法)
如果你想实现更接近$test[$pattern]的原生语法,可以写一个实现ArrayAccess接口的类,把原数组包装起来,这样就能直接用路径字符串作为键来访问:
class PathAccessibleArray implements ArrayAccess { private $originalArray; public function __construct(array $array) { $this->originalArray = $array; } // 判断路径是否存在 public function offsetExists($offset): bool { $keys = $this->parsePath($offset); $current = $this->originalArray; foreach ($keys as $key) { if (!isset($current[$key])) { return false; } $current = $current[$key]; } return true; } // 获取路径对应的值 public function offsetGet($offset): mixed { $keys = $this->parsePath($offset); $current = $this->originalArray; foreach ($keys as $key) { if (!isset($current[$key])) { return null; } $current = $current[$key]; } return $current; } // 设置路径对应的值(可选) public function offsetSet($offset, $value): void { $keys = $this->parsePath($offset); $current = &$this->originalArray; foreach ($keys as $key) { if (!isset($current[$key])) { $current[$key] = []; } $current = &$current[$key]; } $current = $value; } // 删除路径对应的值(可选) public function offsetUnset($offset): void { $keys = $this->parsePath($offset); $lastKey = array_pop($keys); $current = &$this->originalArray; foreach ($keys as $key) { if (!isset($current[$key])) { return; } $current = &$current[$key]; } unset($current[$lastKey]); } // 私有方法:解析路径字符串为键数组 private function parsePath(string $path): array { preg_match_all("/\['(.*?)'\]/", $path, $matches); return $matches[1]; } } // 使用示例 $test = new PathAccessibleArray(['test','test2' => ['test3','test4' => ['test5']]]); $pattern = "['test2']['test4']"; print_r($test[$pattern]); // 输出:Array ( [0] => test5 ) // 还支持设置值 $test["['test2']['test6']"] = 'new value'; print_r($test["['test2']['test6']"]); // 输出:new value
说明
- 这个类实现了PHP的
ArrayAccess接口,所以可以像原生数组一样用[]访问 - 把路径解析逻辑封装成私有方法,代码更整洁
- 还支持设置和删除操作,扩展性很强
内容的提问来源于stack exchange,提问作者Pla558
相关产品推荐
相关产品推荐

