
本文介绍在 PHP 中将形如 'key'=> ['val1', 'val2'] 的字符串安全、可靠地解析为原生关联数组的方法,避免 eval() 风险,并提供健壮的自定义解析函数及实用注意事项。
本文介绍在 php 中将形如 `'key'=> ['val1', 'val2']` 的字符串安全、可靠地解析为原生关联数组的方法,避免 `eval()` 风险,并提供健壮的自定义解析函数及实用注意事项。
在实际开发中,有时会遇到需将结构化字符串(如模拟 PHP 数组语法的字符串)动态转为真实数组的需求。但直接使用 array($string) 仅创建单元素索引数组,无法解析键值与嵌套结构;而滥用 eval() 则存在严重代码注入与安全风险,绝对不推荐。
以下提供两种生产就绪的解析方案,均基于字符串安全拆解与正则辅助,不依赖外部扩展:
✅ 推荐方案:精准分段 + 键值提取(稳定可靠)
function stringToAssocArray(string $input): array
{
// 步骤1:标准化分隔符,用唯一标记替代 ', ' 后的换行/空格干扰(如有)
$clean = preg_replace("/\s+/", " ", trim($input));
// 步骤2:按 `],` 分割各字段(确保不破坏内部逗号)
$segments = preg_split('/\],\s*/', $clean, -1, PREG_SPLIT_NO_EMPTY);
$result = [];
foreach ($segments as $segment) {
// 提取 key:匹配 `'key'=>` 或 `"key"=>`(兼容双引号)
if (preg_match("/^[\s\'\"]+([^\s\'\"]+)[\s\'\"]*=>/", $segment, $keyMatch)) {
$key = $keyMatch[1];
// 提取 value:从 `[` 开始到结尾,去除首尾空格和引号
$valuePart = trim(substr($segment, strpos($segment, '[')));
$valuePart = rtrim($valuePart, ' ]');
// 拆分并清理每个值(支持带引号的字符串)
$values = array_map(function($v) {
return trim($v, " \t\n\r\0\x0B\'\"");
}, explode(',', $valuePart));
$result[$key] = $values;
}
}
return $result;
}
// 使用示例
$string = "'NumDoc'=> ['417', '145'], 'dateDoc'=> ['2022-08-12', '2022-08-13'], 'ValueDoc'=> ['100.00', '150.00']";
$array = stringToAssocArray($string);
print_r($array);
// 输出:
// Array (
// [NumDoc] => Array ([0] => 417, [1] => 145)
// [dateDoc] => Array ([0] => 2022-08-12, [1] => 2022-08-13)
// [ValueDoc] => Array ([0] => 100.00, [1] => 150.00)
// )⚠️ 注意事项与最佳实践
-
永远避免
eval()或create_function():用户输入或不可信来源的字符串执行等同于开放远程代码执行(RCE)入口。 -
输入校验前置:建议先用正则粗筛合法格式,例如
if (!preg_match("/^('[^']+'|\"[^\"]+\")=>\s*\[[^\]]*\](,\s*)*$/", $string)) { throw new InvalidArgumentException('Invalid format'); } -
考虑 JSON 替代方案:若可控数据源,强烈建议改用标准 JSON 格式(如
{"NumDoc":["417","145"],...}),配合json_decode($str, true)—— 更安全、更高效、天然支持嵌套。 -
边界场景处理:当前函数假设值中不含未转义的
],或嵌套数组;如需支持复杂结构(如多维数组),应改用专用解析器(如symfony/yaml或自定义递归解析器)。
✅ 总结
将字符串转为数组的核心在于语义解析而非文本拼接。本文提供的 stringToAssocArray() 函数兼顾可读性、健壮性与安全性,适用于配置注入、低信任度数据桥接等场景。记住:格式化字符串 ≠ 代码,应始终以数据视角解析,而非执行视角对待。

















