我有这样的数组
$arr = [
'baz' => [
'foo' => [
'boo' => 'whatever'
]
]
];
有没有办法使用字符串输入来取消设置 ['boo'] 值?
类似这样的事情
$str = 'baz->foo->boo';
function array_unset($str, $arr) {
// magic here
unset($arr['baz']['foo']['boo']);
return $arr;
}
这个答案非常棒,它是我脚本运行的第一部分使用字符串路径设置嵌套数组数据 。但已经无法逆转了。 附: eval() 不是一个选项:(
由于您无法对引用的元素调用 unset,因此您需要使用另一个技巧:
function array_unset($str, &$arr)
{
$nodes = split("->", $str);
$prevEl = NULL;
$el = &$arr;
foreach ($nodes as &$node)
{
$prevEl = &$el;
$el = &$el[$node];
}
if ($prevEl !== NULL)
unset($prevEl[$node]);
return $arr;
}
$str = "baz->foo->boo";
array_unset($str, $arr);
本质上,您遍历数组树,但保留对最后一个数组(倒数第二个节点)的引用,您要从中删除节点。然后对最后一个数组调用
unset
,将最后一个节点作为键传递。
这个与 Wouter Huysentruit 的类似。不同之处在于,如果传递无效路径,它会返回 null。
function array_unset(&$array, $path)
{
$pieces = explode('.', $path);
$i = 0;
while($i < count($pieces)-1) {
$piece = $pieces[$i];
if (!is_array($array) || !array_key_exists($piece, $array)) {
return null;
}
$array = &$array[$piece];
$i++;
}
$piece = end($pieces);
unset($array[$piece]);
return $array;
}
可能对您有用的即时信息:
$str = 'bar,foo,boo';
function array_unset($str,&$arr) {
$path = explode(',',$str);
$buf = $arr;
for($i=0;$i<count($path)-1;$i++) {
$buf = &$buf[$path[$i]];
}
unset($buf);
}
经过测试、键入、人类可读的版本,抛出无效路径(接受的答案添加无效路径)并处理所有情况:
function array_unset(array &$array, string $path): void {
$previous = null;
foreach (explode('.', $path) as $key) {
if (!isset($array[$key])) {
throw new \InvalidArgumentException(sprintf('Undefined array key "%s".', $key));
}
$previous = &$array;
$array = &$array[$key];
}
/** @var string|int $key */
unset($previous[$key]);
}
用途:
$x = [
'FOO' => 1,
'BAR' => [
['BUZ' => 1],
['BUZ' => 1],
],
];
array_unset($x, 'FOO');
array_unset($x, 'BAR.0.BUZ');
array_unset($x, 'BAR.1');