Php 不会在递归 foreach 循环中中断

Posted

技术标签:

【中文标题】Php 不会在递归 foreach 循环中中断【英文标题】:Php doesn't break in a recursive foreach loop 【发布时间】:2013-01-13 03:08:30 【问题描述】:

我有一个递归函数,如下所示。

public function findnodeintree($cats,$cat_id)
       
    foreach($cats as $node)
                       
        if((int)$node['id'] == $cat_id)
               
            echo "finded";
            $finded = $node;
            break;
        
        else
        
            if(is_array($node) && array_key_exists('children', $node)) 
                $this->findnodeintree($node['children'],$cat_id);
            
                   
    
    return $finded;

举例

$node =$this->findnodeintree($category_Array, 169);

它给了我

"founded"

遇到了 php 错误

Severity: Notice

Message: Undefined variable: finded

数组结构就像

    [0] => Array
    (
        [id] => 0
        [name] => MAIN CATEGORY
        [depth] => 0
        [lft] => 1
        [rgt] => 296
        [children] => Array
            (
                [0] => Array
                    (
                        [id] => 167
                        [name] =>  CAT 0
                        [depth] => 1
                        [lft] => 2
                        [rgt] => 17
                        [children] => Array
                            (
                                [0] => Array
                                    (
                                        [id] => 169
                                        [name] =>   CAT 1
                                        [depth] => 2
                                        [lft] => 3
                                        [rgt] => 4
                                    )

                                [1] => Array
                                    (
                                        [id] => 170
                                        [name] =>   CAT 2
                                        [depth] => 2
                                        [lft] => 5
                                        [rgt] => 10
                                        [children] => Array
                                            (
                                                [0] => Array
                                                    (
                                                        [id] => 171
                                                        [name] =>    CAT 5
                                                        [depth] => 3
                                                        [lft] => 6
                                                        [rgt] => 7
                                                    )

                                                [1] => Array
                                                    (
                                                        [id] => 172
                                                        [name] =>    CAT 3
                                                        [depth] => 3
                                                        [lft] => 8
                                                        [rgt] => 9
                                                    )

                                            )

                                    )

【问题讨论】:

【参考方案1】:

要从递归中获取正确的值,您的递归调用不得丢弃返回值。而且由于您想在命中后立即返回递归树,并实际返回匹配的节点,因此您也必须在该点中断循环。

否则后续的递归调用会覆盖您的变量并返回错误的节点falsenull

这应该是有效的:

public function findnodeintree($cats,$cat_id)
       
    foreach($cats as $node)
                       
        if((int)$node['id'] == $cat_id)       
            return $node;
        
        elseif(array_key_exists('children', $node)) 
            $r = $this->findnodeintree($node['children'], $cat_id);
            if($r !== null)
                return $r;
            
                   
    
    return null;

注意:我删除了is_array,因为此时$node 必须是一个数组或在第一个分支条件下抛出错误。

【讨论】:

【参考方案2】:

将递归行更改为:

 $finded = $this->findnodeintree($node['children'],$cat_id);

您希望能够获取该行,如果您调用该函数,该行必须填充您的变量,否则它将在最后出现的情况下填充,但永远不会将结果返回给您的第一次调用。

因此,$finded 在您的第一次通话中将为空或不存在。

【讨论】:

【参考方案3】:

递归调用 findnodeintree 将经过某些循环,不会“找到”任何东西,但它们仍然返回一个变量 $finded。除了因为在他们的循环中从未找到它,因此确实没有声明该变量。试试这个:

public function findnodeintree($cats,$cat_id)
       
    $finded = NULL;
    foreach($cats as $node)
                       
        if((int)$node['id'] == $cat_id)
               
            echo "finded";
            $finded = $node;
            break;
        
        else
        
            if(is_array($node) && array_key_exists('children', $node)) 
                $this->findnodeintree($node['children'],$cat_id);
            
                   
    
    return $finded;

【讨论】:

以上是关于Php 不会在递归 foreach 循环中中断的主要内容,如果未能解决你的问题,请参考以下文章

前端面试 JavaScript— forEach中return有效果吗?如何中断forEach循环?

php foreach循环大的数据量,在其执行1个多小时后就中断了?有可能是啥原因?

PHP:替换数组值不会在 foreach 循环后保留

for循环与forEach循环的区别

PHP如何在递归函数中计算嵌套调用的级别?

在codeigniter的foreach循环中形成中断