Php 是否从多维数组中删除深度嵌套的元素?

Php 是否从多维数组中删除深度嵌套的元素?,php,arrays,search,Php,Arrays,Search,我需要从未知结构的深度嵌套数组中删除一个元素(也就是说,我不知道为取消设置该元素而寻址该元素的键序列是什么)。但是,我要删除的元素有一个一致的结构(stdObject),因此我可以搜索整个多维数组来找到它,但是必须删除它。关于如何做到这一点的想法 编辑:这是我目前正在尝试实现的功能 function _subqueue_filter_reference(&$where) { foreach ($where as $key => $value) { if (i

我需要从未知结构的深度嵌套数组中删除一个元素(也就是说,我不知道为取消设置该元素而寻址该元素的键序列是什么)。但是,我要删除的元素有一个一致的结构(stdObject),因此我可以搜索整个多维数组来找到它,但是必须删除它。关于如何做到这一点的想法

编辑:这是我目前正在尝试实现的功能

function _subqueue_filter_reference(&$where)
{
    foreach ($where as $key => $value) {
        if (is_array($value))
        {
            foreach ($value as $filter_key => $filter)
            {
                if (isset($filter['field']) && is_string($filter['field']) && $filter['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
                {
                    unset($value[$filter_key]);
                    return TRUE;
                }
            }
            return _subqueue_filter_reference($value);
        }
    }
    return FALSE;
}
编辑#2:
var#u dump
截取数组结构

array (size=1)
  1 => 
    array (size=3)
      'conditions' => 
        array (size=5)
          0 => 
            array (size=3)
              ...
          1 => 
            array (size=3)
              ...
          2 => 
            array (size=3)
              ...
          3 => 
            array (size=3)
              ...
          4 => 
            array (size=3)
              ...
      'args' => 
        array (size=0)
          empty
      'type' => string 'AND' (length=3)
…因此,假设将整个结构分配给
$array
,我需要删除的元素是
$array[1]['conditions'][4]
,其中目标是一个包含三个字段的数组:

  • 价值观
  • 接线员

…所有这些都是字符串值。

解决此问题的一种方法是使用第二个参数扩展递归函数:

function _subqueue_filter_reference(&$where, $keyPath = array())
您仍然会以相同的方式进行初始调用,但对自身的内部调用如下:

return _subqueue_filter_reference($value, array_merge($keyPath, array($key)));
这将为您提供键的完整路径,以到达
$keyPath
变量中数组的当前部分。然后,您可以在
取消设置中使用此选项。如果你觉得自己很脏,你甚至可以使用
eval
作为一个有效的快捷方式,因为输入的来源完全在你的控制范围内


编辑:另一方面,在数组上循环时从数组中删除项目可能不是一个好主意。我不确定foreach是如何编译的,但如果您遇到奇怪的错误,您可能需要将查找逻辑与删除逻辑分开。

这只是光标问题

function recursive_unset(&$array)
{
    foreach ($array as $key => &$value) # See the added & here.
    {
        if(is_array($value))
        {
            if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
            {
                unset($array[$key]);
            }
            recursive_unset($value);
        }
    }
}
注意:这里不需要使用is_字符串,只需在与字符串进行比较且值存在时进行比较即可

除非您确定您的值只出现一次,否则不要使用return

编辑:

下面是一个完整的示例,其数组与您展示的类似:

$test = array (
        1 => array (
                'conditions' =>
                array (
                        0 => array ('field' => 'dont_care1', 'value' => 'test', 'operator' => 'whatever'),
                        1 => array ('field' => 'dont_care2', 'value' => 'test', 'operator' => 'whatever'),
                        2 => array ('field' => 'nodequeue_nodes_node__nodequeue_subqueue.reference', 'value' => 'test', 'operator' => 'whatever'),
                        3 => array ('field' => 'dont_care3', 'value' => 'test', 'operator' => 'whatever')
                ),
        'args' => array (),
        'type' => 'AND'
));

var_dump($test);

function recursive_unset(&$array)
{
    foreach ($array as $key => &$value)
    {
        if(is_array($value))
        {
            if(isset($value['field']) && $value['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
            {
                unset($array[$key]);
            }
            recursive_unset($value);
        }
    }
}

recursive_unset($test);

var_dump($test);

我已经找到了一个解决方案,它是(
array\u search
documentation)中的函数的衍生产品

代码:

我讨厌使用eval,因为它会造成巨大的、巨大的安全漏洞,但它非常安全,eval中调用的值是由Drupal核心和视图显式生成的。我现在可以用它了


无论如何,当我返回树时,我只是用新返回的树数组替换旧数组。工作起来很有魅力。

我已经读过这篇文章,但它没有回答我的问题。如果我知道深嵌套元素的确切键序列,那么使用
unset
将很容易,但是我不知道。你知道你必须搜索它。所以当你发现它时,用unset。也许我不明白。搜索并删除…对吗?刚刚在三维数组上测试了这段代码,它成功了。但是,如果“字段”位于数组的第一级,它将不起作用(不会删除数组本身)。我添加了正在搜索的数组结构示例。编辑以显示完整的代码。仍然适用于我的采样阵列。也许可以展示你所做代码的实现?将是比评估更好的解决方案。
function _subqueue_filter_reference($haystack,&$tree=array(),$index="")
{
    // dpm($haystack);
    if (is_array($haystack))
    {

        $result = array();

        if (count($tree)==0)
        {
            $tree = array() + $haystack;
        }

        foreach($haystack as $k=>$current)
        {
            if (is_array($current))
            {
                if (isset($current['field']) && is_string($current['field']) && $current['field'] == 'nodequeue_nodes_node__nodequeue_subqueue.reference')
                {
                    eval("unset(\$tree{$index}[{$k}]);"); // unset all elements = empty array
                }
                _subqueue_filter_reference($current,$tree,$index."[$k]");
            }
        } 
    } 
    return $tree;
}