在 PHP 中满足某个条件时如何停止递归循环
Posted
技术标签:
【中文标题】在 PHP 中满足某个条件时如何停止递归循环【英文标题】:How to stop a recursive loop when a certain condition is met in PHP 【发布时间】:2022-01-16 02:37:00 【问题描述】:我有一个以下结构的数组,我想将元素从根级别获取到第 3 级
Array
(
[0] => Array
(
[id] => 1
[parent_id] =>
[name] => try
[sub_categories] => Array
(
[0] => Array
(
[id] => 2
[parent_id] => 1
[name] => try1
[sub_categories] => Array
(
[0] => Array
(
[id] => 3
[parent_id] => 2
[name] => try2
[sub_categories] => Array
(
[0] => Array
(
[id] => 4
[parent_id] => 3
[name] => try3
[sub_categories] => Array
(
[0] => Array
(
[id] => 5
[parent_id] => 4
[name] => try4
)
)
)
)
)
)
)
)
(
[1] => Array
(
[id] => 6
[parent_id] => 1
[name] => try1
[sub_categories] => Array
(
[0] => Array
(
[id] => 7
[parent_id] => 6
[name] => try2
[sub_categories] => Array
(
[0] => Array
(
[id] => 8
[parent_id] => 7
[name] => try3
[sub_categories] => Array
(
[0] => Array
(
[id] => 9
[parent_id] => 8
[name] => try4
)
)
)
)
)
)
)
)
)
)
public function getElements( $parent_id = NULL, $level = 0 )
$data = models\Categories::find()->where( ['parent_id'=>$parent_id] )->all();
$arr = array();
foreach( $data as $data )
if( $level == 3 )
break;
//do something
$countChilds = models\Categories::find()->where( ['parent_id'=>$data->id] )->count();
if( $countChilds > 0 )
$catData['sub_categories'] = $this->getElements( $parent_id = $data->id, $level++ );
$arr[] = $catData;
return $arr;
我尝试添加一个计数器并在计数器变为 3 时跳出循环但它不起作用,所以我认为因为计数器只能在根类别旁边的直接子类别上工作,因为我想下到树 3 层,所以计数器不工作什么是实现这一目标的最佳方法我希望我的结果数组输出一个 ID 为 1,2,3,4 , 6,7 的数组, 8. ID 为 5,9 的元素不应打印,因为它们属于级别 4
对此的任何帮助将不胜感激
【问题讨论】:
看起来您正在在循环中运行数据库查询 - 这会给您带来非常糟糕的运行时性能。相反,为什么不能使用带有自引用 CTE 的 SQL 查询?这样,您根本不需要使用太多 php 代码来进行查找,只需一个 fast SQL 查询。 @Dai 感谢您的观察,但我输入错误,我应该写 getElements 而我写了 getAll(),我已经对此进行了更正if( level == 3 )
这应该是if( $level == 3 )
@Daiam 也可以使用 SQL 查询,但我不知道如何在满足此条件时停止查询,因为我的数据库中没有具有级别的列
@chaos505 谢谢,这是我在这里写问题时的拼写错误
【参考方案1】:
<?php
public function getElements( $parent_id = NULL, $level = 0 )
if( $level == 3 ) return []; // or return $arr;
$data = models\Categories::find()->where( ['parent_id'=>$parent_id] )->all();
$arr = array();
foreach( $data as $data )
//do something
$countChilds = models\Categories::find()->where( ['parent_id'=>$data->id] )->count();
if( $countChilds > 0 )
$catData['sub_categories'] = $this->getElements( $parent_id = $data->id, $level + 1);
$arr[] = $catData;
return $arr;
在上面的代码中,我做了两处改动。
如果是$level == 3
,则立即返回。无需将其放在 foreach 中。
它应该是 $catData['sub_categories'] = $this->getElements( $parent_id = $data->id, $level + 1);
而不是$level++
,因为子级将有父级+ 1,而后递增运算符不会这样做。此外,即使 ++$level
(pre-increment operation) 也不是一个好主意,因为即使对于 foreach 循环中下一个即将出现的条目,您也在修改变量。所以,$level + 1
是正确的方式。
【讨论】:
非常感谢,您说得对,增量操作不适用于 level + 1 它确实可以正常工作 @sam 很高兴它成功了。以上是关于在 PHP 中满足某个条件时如何停止递归循环的主要内容,如果未能解决你的问题,请参考以下文章
VS调试技巧:如何让断点在for循环中变量满足某个条件的时候停下来(条件调试)
VS调试技巧:如何让断点在for循环中变量满足某个条件的时候停下来(条件调试)