尝试遍历DB中的树形结构数据
表是这样的
main_id sub_id
------------------------
1 2
1 3
2 4
3 5
我的功能如下:
$sql="Select * from info_map where main_id= ? ";
$stmt=$conn->prepare($sql);
if(!$stmt){ throw new Exception ( implode(' ',$conn->errorInfo()),0); }
search_child($stmt,215);
function search_child($stmt,$mom){
$res=$stmt->execute(array($mom));
if(!$res){ throw new Exception( implode(' ',$stmt->errorInfo()),1); }
$rc=$stmt->rowCount();
if($rc>0){
while($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)){
$nextMom=$row['sub_id'];
echo $mom.'->'.$nextMom.'<br>';
search_child($stmt,$nextMom);
}
}
$stmt=$conn->prepare()
在函数内,我得到了我想要的结果(返回所有的孩子和他们的孙子....等)
,但它没有重用prepare语句,因为我们运行相同的sql。
所以我把$stmt=$conn->prepare()
移出函数,就像上面的代码一样,但这样它只返回一个子节点和它的孙子节点。
我可以在递归函数中重用这样的语句对象吗?还是我做错了什么?
更新:@Barmar你的回复帮助我意识到为什么我只有一行家谱,因为当循环回到第二代的第二个孩子时,语句obj已经消失了,因为它已经被用于其他一代的查询(第二代的第一个孩子的后代),谢谢。
正如@Barmar所暗示的,php和mysql服务器之间可能存在一些冲突。我通常为我的递归函数传递准备好的语句没有问题,但通过fetchAll()
这样得到结果:
function search_child($stmt,$mom){
$res=$stmt->execute(array($mom));
if(!$res){ throw new Exception( implode(' ',$stmt->errorInfo()),1); }
foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row){
// PDO fetch orientation is next by default. no need to specify it.
$nextMom=$row['sub_id'];
echo $mom.'->'.$nextMom.'<br>';
search_child($stmt,$nextMom);
}
}